Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8eb2806
feat: initial kustomize-traverse implementation
Apr 22, 2026
149a629
test: add e2e tests that exec the built binary
Apr 22, 2026
44abb9b
docs: add SPEC.md and CI.md
Apr 23, 2026
2cd732e
docs: add README.md, refine SPEC.md and CI.md
Apr 23, 2026
e1c9a9f
docs: library usage, testing strategy, Envoy Gateway, logging
Apr 24, 2026
ccec90e
refactor: extract traverse package, rename module to y-cluster
Apr 24, 2026
0c4c6f6
feat: add yconverge package with CUE parsing and check runner
Apr 23, 2026
a50a483
feat: add dependency resolution and Run() orchestrator
Apr 23, 2026
b0d44e1
feat: add cobra CLI, validate against real cluster
Apr 23, 2026
aba992f
feat: support kubectl-yconverge plugin invocation
Apr 23, 2026
8fe8e82
test: add unit tests for ParseChecks
Apr 24, 2026
1fab600
docs: add TESTING.md for maintainers
Apr 24, 2026
5db1df7
docs: provider detection, coverage tracking, remote runtime constraints
Apr 24, 2026
2cffaf2
docs: use testcontainers-go for e2e test harness
Apr 24, 2026
1892a6f
docs: replace testcontainers-go with Moby client for e2e harness
Apr 24, 2026
e2d9ef4
test: add yconverge e2e tests with kwok cluster
Apr 24, 2026
bbccf83
test: rewrite e2e with db/backend/frontend model, fix overlay dep res…
Apr 24, 2026
2c9d1e9
test: prove checks gate next apply via marker pattern
Apr 24, 2026
b9b135f
feat: add QEMU provisioner with CLI and e2e tests
Apr 24, 2026
e2cc81f
feat: add kubeconfig package for cross-provisioner context management
Apr 24, 2026
bada6a9
docs: questions to cluster maintainers on spec vs reality
Apr 24, 2026
cff6a94
docs: answer all 21 maintainer questions with rationale from implemen…
Apr 24, 2026
af343d4
specifies the next feature to implement in y-cluster
solsson Apr 24, 2026
e4d5649
spec reviewed by the ystack appliance agent
Apr 24, 2026
050767c
docs: plan for y-cluster serve feature
Apr 24, 2026
c8a5f19
docs: plan for y-cluster serve feature -- answers
solsson Apr 24, 2026
4299e57
test(serve): failing e2e + y-kustomize-bases fixture
Apr 24, 2026
1e17d1d
feat(serve): y-cluster serve subcommand with y-kustomize-local backend
Apr 24, 2026
31c193a
ci: lint + e2e-serve job; release-asset validation workflow
Apr 24, 2026
ab7b773
Bail on secretGenerator file renames in y-kustomize-local sources
Apr 24, 2026
7ce5afc
feat(serve): rename check via kustomize types; cover configMapGenerator
Apr 24, 2026
ad102c4
ci: publish ghcr.io/yolean/y-cluster image via turbokube/contain
Apr 24, 2026
67102c6
docs: release pipeline plan -- build once, multi-arch images, reuse
Apr 24, 2026
1aae344
docs(plan): record D1 answer -- one workflow, one build matrix
Apr 24, 2026
a538e7b
docs(plan): record D3-D5 -- raw release assets, no new archs, defer c…
Apr 24, 2026
822d21f
ci: consolidated pipeline -- one build matrix, multi-arch image, raw …
Apr 24, 2026
f6b7743
ci: use solsson/setup-contain@v1 to install contain
Apr 24, 2026
45cbdc1
docs: a bit more info about subcommands
solsson Apr 24, 2026
91d815c
ci: fix actions/download-artifact@v4.3.0 commit SHA
Apr 24, 2026
da109cc
ci: satisfy errcheck by excluding noise + propagating real errors
Apr 24, 2026
e62cb0c
ci: upgrade to golangci-lint-action v9.2.0 and golangci-lint v2.11.4
Apr 24, 2026
303cbe8
ci: bump all GitHub-maintained actions to Node.js 24 releases
Apr 24, 2026
208b8c9
feat(serve): implement y-kustomize-in-cluster and static backends
Apr 24, 2026
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
194 changes: 189 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,203 @@
name: CI

# Consolidated pipeline per RELEASE_PIPELINE_PLAN.md.
#
# One workflow, one `build` matrix, one source of truth for binaries.
# Every consumer (e2e-serve, image, release-assets) pulls from the
# uploaded artifacts so a tag run ships the same bytes everywhere.
#
# Triggers:
# push main → lint, test, build, e2e-serve, image(sha)
# push tag v* → all of the above + image(tag) + release-assets
# pull_request → lint, test, build, e2e-serve only
# workflow_dispatch → same as push main
#
# Image is only published under Yolean (not YoleanAgents) — the `if:`
# on the image/release-assets jobs is belt-and-braces; the human owner
# mirrors manually when ready to open-source.

on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
workflow_call:
workflow_dispatch:

jobs:
# --- PR and main checks ---

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
version: v2.11.4
args: --timeout=5m

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- run: go test ./...
- run: go test -count=1 ./...
- run: go vet ./...

# --- Single source of truth for y-cluster binaries ---

build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
- goos: linux
goarch: arm64
- goos: darwin
goarch: amd64
- goos: darwin
goarch: arm64
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
cache: true
- name: Build y-cluster
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
mkdir -p cmd/y-cluster/target/${GOOS}/${GOARCH}
go build -trimpath \
-ldflags "-s -w -X main.version=${GITHUB_REF_NAME}" \
-o cmd/y-cluster/target/${GOOS}/${GOARCH}/y-cluster \
./cmd/y-cluster
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: y-cluster-${{ matrix.goos }}-${{ matrix.goarch }}
path: cmd/y-cluster/target/${{ matrix.goos }}/${{ matrix.goarch }}/y-cluster
retention-days: 7
if-no-files-found: error

# --- E2e against the freshly-built linux/amd64 binary ---

e2e-serve:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: y-cluster-linux-amd64
path: bin
- name: Run serve e2e against the built binary
env:
Y_CLUSTER_BIN: ${{ github.workspace }}/bin/y-cluster
run: |
chmod +x "$Y_CLUSTER_BIN"
./scripts/e2e-serve-against-binary.sh

# --- Multi-arch image via contain, blocked on all prior jobs ---

image:
runs-on: ubuntu-latest
needs: [lint, test, build, e2e-serve]
if: github.repository_owner == 'Yolean' && github.event_name != 'pull_request'
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Download linux/amd64 binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: y-cluster-linux-amd64
path: cmd/y-cluster/target/linux/amd64

- name: Download linux/arm64 binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: y-cluster-linux-arm64
path: cmd/y-cluster/target/linux/arm64

- uses: solsson/setup-contain@49cc4cce1498df8a59e88fff52c1a9b747f11f08 # v1
with:
version: v0.9.0

- name: Log in to GitHub Container Registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push image (SHA tag)
working-directory: cmd/y-cluster
env:
IMAGE: ghcr.io/yolean/y-cluster:${{ github.sha }}
run: contain build

- name: Build and push image (release tag)
if: startsWith(github.ref, 'refs/tags/v')
working-directory: cmd/y-cluster
env:
IMAGE: ghcr.io/yolean/y-cluster:${{ github.ref_name }}
run: contain build

# --- Release assets on tag push: raw binaries, no compression ---

release-assets:
runs-on: ubuntu-latest
needs: image
if: startsWith(github.ref, 'refs/tags/v') && github.repository_owner == 'Yolean'
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: y-cluster-*
path: downloaded

- name: Rename binaries (goreleaser naming) and checksum
id: assets
run: |
set -euo pipefail
tag="${GITHUB_REF_NAME}"
mkdir -p release
for d in downloaded/y-cluster-*; do
# Each artifact dir contains a single `y-cluster` binary.
base=$(basename "$d") # y-cluster-linux-amd64
suffix=${base#y-cluster-} # linux-amd64
os=${suffix%-*} # linux
arch=${suffix#*-} # amd64
cp "$d/y-cluster" "release/y-cluster_${tag}_${os}_${arch}"
chmod +x "release/y-cluster_${tag}_${os}_${arch}"
done
(cd release && sha256sum y-cluster_${tag}_* > "y-cluster_${tag}_checksums.txt")
ls -l release/

- name: Publish release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
tag="${GITHUB_REF_NAME}"
# Idempotent: create the release if it does not yet exist,
# then upload (or re-upload) all assets.
gh release view "$tag" >/dev/null 2>&1 \
|| gh release create "$tag" --title "$tag" --generate-notes --verify-tag
gh release upload "$tag" release/y-cluster_${tag}_* --clobber
67 changes: 67 additions & 0 deletions .github/workflows/e2e-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: e2e Release

# Validates that an actually-published y-cluster release asset works
# end-to-end on the platforms we support. Runs on release publication
# and can be re-run manually against any published tag. The asset shape
# is the raw-binary convention from ci.yaml:
# y-cluster_<tag>_<os>_<arch> plus y-cluster_<tag>_checksums.txt.

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Release tag to test"
required: true

jobs:
serve:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
os_slug: linux
arch: amd64
- os: macos-latest
os_slug: darwin
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Resolve tag
id: tag
shell: bash
run: |
if [ -n "${{ github.event.release.tag_name }}" ]; then
echo "tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
fi

- name: Download release asset and verify checksum
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
tag='${{ steps.tag.outputs.tag }}'
asset="y-cluster_${tag}_${{ matrix.os_slug }}_${{ matrix.arch }}"
sums="y-cluster_${tag}_checksums.txt"
gh release download "$tag" \
--repo Yolean/y-cluster \
--pattern "$asset" \
--pattern "$sums" \
--dir .
grep " $asset\$" "$sums" | sha256sum --check -
chmod +x "$asset"
mv "$asset" y-cluster
./y-cluster --version

- name: Run serve e2e against the release binary
shell: bash
env:
Y_CLUSTER_BIN: ./y-cluster
run: ./scripts/e2e-serve-against-binary.sh
30 changes: 0 additions & 30 deletions .github/workflows/release.yaml

This file was deleted.

28 changes: 28 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "2"
run:
timeout: 5m
linters:
default: none
enable:
- errcheck
- govet
- staticcheck
- unused
settings:
errcheck:
# Functions whose returned error is idiomatically ignored.
# Real write/exec operations are not excluded -- failures there
# hide bugs. This list is restricted to noise-only patterns.
exclude-functions:
# Writing to stdout/stderr rarely errors meaningfully.
- fmt.Fprint
- fmt.Fprintf
- fmt.Fprintln
# Deferred Close() on files, HTTP response bodies, pipes.
- (io.Closer).Close
- (*os.File).Close
# Test env helpers and best-effort cleanup.
- os.Setenv
- os.Unsetenv
- os.Remove
- os.RemoveAll
52 changes: 0 additions & 52 deletions .goreleaser.yaml

This file was deleted.

Loading