Skip to content
Open
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
45 changes: 45 additions & 0 deletions .fabrica.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

project:
name: testbed
module: github.com/openchami/github-actions-testbed
description: Fabrica testbed for the OpenCHAMI github-actions workflows
created: 2026-10-20T09:31:45.79078442-06:00
features:
validation:
enabled: true
mode: strict
events:
enabled: false
bus_type: memory
conditional:
enabled: true
etag_algorithm: sha256
auth:
enabled: false
storage:
enabled: true
type: file
db_driver: sqlite3
metrics:
enabled: false
provider: prometheus
reconciliation:
enabled: false
worker_count: 5
requeue_delay: 5
security:
authn:
enabled: false
authz:
enabled: false
mode: enforce
generation:
handlers: true
storage: true
client: true
openapi: true
events: false
middleware: true
reconciliation: false
7 changes: 6 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ jobs:
lint-makefile-common:
uses: OpenCHAMI/github-actions/.github/workflows/lint-makefile-common.yml@5a0ca6e79ffd9f8db2b517beb176039628d22095 # github-actions under test (seantronsen/feat/release-attestation)

lint-codegen-fabrica:
uses: OpenCHAMI/github-actions/.github/workflows/lint-codegen-fabrica.yml@ce924a777ca3efdd577e4e81d2819a1f14260935 # github-actions under test (seantronsen/feat/release-attestation)
with:
go-version-file: go.mod

lint:
if: ${{ always() }}
needs: [lint-go, lint-ci, lint-renovate, lint-makefile-common]
needs: [lint-go, lint-ci, lint-renovate, lint-makefile-common, lint-codegen-fabrica]
runs-on: ubuntu-slim
steps:
- uses: re-actors/alls-green@b5b5b37504aa4183270bd3d855c52a67f212be35 # v1.3.0
Expand Down
9 changes: 5 additions & 4 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@ before:

builds:
- id: testbed
main: ./cmd/testbed
main: ./cmd/server
binary: testbed
goos: [linux]
goarch: [amd64, arm64]
env:
- CGO_ENABLED=0
# Version variables declared by Fabrica's generated version_generated.go.
ldflags:
- >-
-s -w
-X main.version={{ .Version }}
-X main.commit={{ .Commit }}
-X main.buildHost={{ .Env.BUILD_HOST }}
-X main.serviceVersion={{ .Version }}
-X main.serviceCommit={{ .Commit }}
-X main.serviceDate={{ .Date }}

archives:
- id: testbed
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ FROM gcr.io/distroless/static
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/testbed /usr/bin/testbed
ENTRYPOINT ["/usr/bin/testbed"]
CMD ["serve"]
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
IMAGE_TAG ?= $(shell git describe --tags --always --abbrev=0)
QUADLET_DIR ?= build/quadlet
CLEANFILES := bin/ build/ dist/
# cmd/client is Fabrica's generated CLI; only the server ships.
BINARIES := testbed:./cmd/server

include Makefile.common

Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,25 @@ image (`dockers_v2`), rpm/deb quadlet packages, attestations, and the GitHub
release, plus release signing (`checksums.txt`, through the repo's real key
chain, like any other OpenCHAMI repo).

It's also a minimal [Fabrica](https://github.com/OpenCHAMI/fabrica) project
(one `Widget` resource, file storage), so `lint-codegen-fabrica` has generated
code to check. Edit `apis/` or `.fabrica.yaml`, run `make generate`, and commit
the result; `make generate-check` is what CI runs.

## Using this as a template

1. Copy `.github/workflows/`, `.goreleaser.yaml`, `Dockerfile`, `Makefile`'s
`quadlet-render` target, and `packaging/`.
2. Rename `testbed` / `github-actions-testbed` to your project (binary, image,
package name, quadlet, URLs, badges).
3. Update the expected package file lists in `build.yml` and `release.yml`
3. For a Fabrica project, keep the `lint-codegen-fabrica` job in `lint.yml`;
otherwise drop it.
4. Update the expected package file lists in `build.yml` and `release.yml`
(`validate-packages`): rpm lists every file and owned directory, deb only
files.
4. Pin `OpenCHAMI/github-actions` to a release (or SHA) instead of the testbed's
5. Pin `OpenCHAMI/github-actions` to a release (or SHA) instead of the testbed's
branch pin.
5. Provision your repo's key as the `GPG_REPO_CERT_KEY_B64` secret; `sign`
6. Provision your repo's key as the `GPG_REPO_CERT_KEY_B64` secret; `sign`
also reads the `MASTER_PUBLIC_ASC` / `MASTER_FPR` org secrets. Annotated
GoReleaser reference:
[`.goreleaser.example.yml`](https://github.com/OpenCHAMI/github-actions/blob/main/.goreleaser.example.yml).
Expand Down
10 changes: 10 additions & 0 deletions apis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

groups:
- name: testbed.openchami.io
storageVersion: v1
versions:
- v1
resources:
- Widget
62 changes: 62 additions & 0 deletions apis/testbed.openchami.io/v1/widget_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package v1

import (
"context"
"github.com/openchami/fabrica/pkg/fabrica"
)

// Widget represents a widget resource
type Widget struct {
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
Kind string `json:"kind" yaml:"kind"`
Metadata fabrica.Metadata `json:"metadata" yaml:"metadata"`
Spec WidgetSpec `json:"spec" yaml:"spec" validate:"required"`
Status WidgetStatus `json:"status,omitempty" yaml:"status,omitempty"`
}

// WidgetSpec defines the desired state of Widget
type WidgetSpec struct {
Description string `json:"description,omitempty" yaml:"description,omitempty" validate:"max=200"`
// Add your spec fields here
}

// WidgetStatus defines the observed state of Widget
type WidgetStatus struct {
Phase string `json:"phase,omitempty" yaml:"phase,omitempty"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Ready bool `json:"ready" yaml:"ready"`
// Add your status fields here
}

// Validate implements custom validation logic for Widget
func (r *Widget) Validate(ctx context.Context) error {
// Add custom validation logic here
// Example:
// if r.Spec.Description == "forbidden" {
// return errors.New("description 'forbidden' is not allowed")
// }

return nil
}

// GetKind returns the kind of the resource
func (r *Widget) GetKind() string {
return "Widget"
}

// GetName returns the name of the resource
func (r *Widget) GetName() string {
return r.Metadata.Name
}

// GetUID returns the UID of the resource
func (r *Widget) GetUID() string {
return r.Metadata.UID
}

// IsHub marks this as the hub/storage version
func (r *Widget) IsHub() {}
27 changes: 27 additions & 0 deletions apis/testbed.openchami.io/v1/widget_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
// SPDX-License-Identifier: MIT

package v1

import (
"context"
"testing"

"github.com/openchami/fabrica/pkg/fabrica"
)

func TestWidget(t *testing.T) {
w := &Widget{Metadata: fabrica.Metadata{Name: "w1", UID: "uid-1"}}
if got := w.GetKind(); got != "Widget" {
t.Errorf("GetKind() = %q, want %q", got, "Widget")
}
if got := w.GetName(); got != "w1" {
t.Errorf("GetName() = %q, want %q", got, "w1")
}
if got := w.GetUID(); got != "uid-1" {
t.Errorf("GetUID() = %q, want %q", got, "uid-1")
}
if err := w.Validate(context.Background()); err != nil {
t.Errorf("Validate() = %v, want nil", err)
}
}
Loading
Loading