Skip to content
Draft
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
129 changes: 46 additions & 83 deletions .github/workflows/PRBuild.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Copyright © 2025 OpenCHAMI a Series of LF Projects, LLC
#
# Copyright © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: Build each PR for testing and validation

on:
pull_request:
branches:
Expand All @@ -17,91 +15,56 @@ on:
type: string

permissions: write-all # Necessary for the generate-build-provenance action with containers

jobs:

build:


config:
runs-on: ubuntu-latest

outputs:
rpm-unsigned: ${{ steps.names.outputs.rpm-unsigned }}
rpm-signed: ${{ steps.names.outputs.rpm-signed }}
keys-public: ${{ steps.names.outputs.keys-public }}
steps:
- name: Set up latest stable Go
uses: actions/setup-go@v6.4.0
with:
go-version: stable
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:master
network=host
- name: Docker Login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v6.0.2
with:
fetch-tags: 1
fetch-depth: 0
# Set environment variables required by GoReleaser
- name: Set build environment variables
- id: names
run: |
echo "GIT_STATE=$(if git diff-index --quiet HEAD --; then echo 'clean'; else echo 'dirty'; fi)" >> $GITHUB_ENV
echo "BUILD_HOST=$(hostname)" >> $GITHUB_ENV
echo "GO_VERSION=$(go version | awk '{print $3}')" >> $GITHUB_ENV
echo "BUILD_USER=$(whoami)" >> $GITHUB_ENV
echo "CGO_ENABLED=0" >> $GITHUB_ENV
echo "IS_PR_BUILD=true" >> $GITHUB_ENV
{
echo "rpm-unsigned=rpms-unsigned"
echo "rpm-signed=rpms-signed"
echo "keys-public=public-keys"
} >> "$GITHUB_OUTPUT"

- name: Docker Login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
build:
uses: OpenCHAMI/github-actions/.github/workflows/build-publish-container-goreleaser.yml@dev-rpm-quadlets
secrets: inherit
with:
cgo_enabled: 0
registry_subject_name: ghcr.io/openchami/metadata-service
is_pr_build: true
pr_number: ${{ inputs.pr_number || github.event.pull_request.number || 0 }}

- name: Create Tag for PR
if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.pr_number != '')
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
PR_NUM="${{ github.event.number }}"
if [[ "${{ inputs.pr_number }}" != "" ]]; then
PR_NUM="${{ inputs.pr_number }}"
fi
git tag -f -a pr-${PR_NUM} -m "PR Release"
rpmbuild:
needs: [config, build]
uses: OpenCHAMI/github-actions/.github/workflows/build-rpm-quadlet.yml@dev-rpm-quadlets
secrets: inherit
with:
artifact-name-unsigned-rpms: ${{ needs.config.outputs.rpm-unsigned }}

- name: Build/Push container with goreleaser
uses: goreleaser/goreleaser-action@v6
env:
GITHUB_TOKEN: ${{ github.token }}
with:
version: '~> 2'
args: release --clean --skip=announce,validate,archive
id: goreleaser
- name: Process goreleaser output
id: process_goreleaser_output
run: |
echo "const fs = require('fs');" > process.js
echo 'const artifacts = ${{ steps.goreleaser.outputs.artifacts }}' >> process.js
echo "const firstNonNullDigest = artifacts.find(artifact => artifact.extra && artifact.extra.Digest != null)?.extra.Digest;" >> process.js
echo "console.log(firstNonNullDigest);" >> process.js
echo "fs.writeFileSync('digest.txt', firstNonNullDigest);" >> process.js
node process.js
echo "digest=$(cat digest.txt)" >> $GITHUB_OUTPUT
- name: Attest Binaries
uses: actions/attest-build-provenance@v4.1.0
with:
subject-path: dist/**
- name: generate build provenance
uses: actions/attest-build-provenance@v4.1.0
with:
subject-name: ghcr.io/openchami/metadata-service
subject-digest: ${{ steps.process_goreleaser_output.outputs.digest }}
push-to-registry: true
rpmsign:
needs: [config, rpmbuild]
uses: OpenCHAMI/github-actions/.github/workflows/gpg-sign-artifacts.yml@dev-rpm-quadlets
secrets: inherit
with:
artifact-name-unsigned-rpms: ${{ needs.config.outputs.rpm-unsigned }}
artifact-name-signed-rpms: ${{ needs.config.outputs.rpm-signed }}
artifact-name-public-keys: ${{ needs.config.outputs.keys-public }}

rpmvalidate:
needs: [config, rpmsign]
uses: OpenCHAMI/github-actions/.github/workflows/validate-rpm-quadlet.yml@dev-rpm-quadlets
secrets: inherit
with:
artifact-name-signed-rpms: ${{ needs.config.outputs.rpm-signed }}
expected-files: |
/usr/share/containers/systemd/metadata-data.volume
/usr/share/containers/systemd/metadata-service.container
/usr/share/licenses/metadata-service
/usr/share/licenses/metadata-service/MIT.txt
106 changes: 36 additions & 70 deletions .github/workflows/Release.yaml
Original file line number Diff line number Diff line change
@@ -1,83 +1,49 @@
# Copyright © 2025 OpenCHAMI a Series of LF Projects, LLC
#
# Copyright © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: Release with goreleaser

name: Release
on:
workflow_dispatch:
push:
tags:
- v*

permissions: write-all # Necessary for the generate-build-provenance action with containers
env:
ARTIFACT_NAME_RPM_UNSIGNED: 'rpms-unsigned'
ARTIFACT_NAME_RPM_SIGNED: 'rpms-signed'
ARTIFACT_NAME_GPG_KEYS_PUBLIC: 'gpg-public-keys'

jobs:

build:


runs-on: ubuntu-latest

steps:
- name: Set up latest stable Go
uses: actions/setup-go@v6.4.0
with:
go-version: stable
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:master
network=host
- name: Docker Login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v6.0.2
with:
fetch-tags: 1
fetch-depth: 0
# Set environment variables required by GoReleaser
- name: Set build environment variables
run: |
echo "GIT_STATE=$(if git diff-index --quiet HEAD --; then echo 'clean'; else echo 'dirty'; fi)" >> $GITHUB_ENV
echo "BUILD_HOST=$(hostname)" >> $GITHUB_ENV
echo "GO_VERSION=$(go version | awk '{print $3}')" >> $GITHUB_ENV
echo "BUILD_USER=$(whoami)" >> $GITHUB_ENV
echo "CGO_ENABLED=0" >> $GITHUB_ENV
echo "IS_PR_BUILD=false" >> $GITHUB_ENV

- name: Release with goreleaser
uses: goreleaser/goreleaser-action@v6
env:
GITHUB_TOKEN: ${{ github.token }}
with:
version: latest
args: release --clean
id: goreleaser
- name: Process goreleaser output
id: process_goreleaser_output
run: |
echo "const fs = require('fs');" > process.js
echo 'const artifacts = ${{ steps.goreleaser.outputs.artifacts }}' >> process.js
echo "const firstNonNullDigest = artifacts.find(artifact => artifact.extra && artifact.extra.Digest != null)?.extra.Digest;" >> process.js
echo "console.log(firstNonNullDigest);" >> process.js
echo "fs.writeFileSync('digest.txt', firstNonNullDigest);" >> process.js
node process.js
echo "digest=$(cat digest.txt)" >> $GITHUB_OUTPUT
- name: Attest Binaries
uses: actions/attest-build-provenance@v1
with:
subject-path: dist/**
- name: generate build provenance
uses: actions/attest-build-provenance@v1
with:
subject-name: ghcr.io/openchami/metadata-service
subject-digest: ${{ steps.process_goreleaser_output.outputs.digest }}
push-to-registry: true
uses: OpenCHAMI/github-actions/.github/workflows/build-publish-container-goreleaser.yml@dev-rpm-quadlets
secrets: inherit
with:
cgo_enabled: 0
is_pr_build: false
registry_subject_name: ghcr.io/openchami/metadata-service

rpmbuild:
needs: build
uses: OpenCHAMI/github-actions/.github/workflows/build-rpm-quadlet.yml@dev-rpm-quadlets
secrets: inherit
with:
artifact-name-unsigned-rpms: ${{ env.ARTIFACT_NAME_RPM_UNSIGNED }}

rpmsign:
needs: rpmbuild
uses: OpenCHAMI/github-actions/.github/workflows/gpg-sign-artifacts.yml@dev-rpm-quadlets
secrets: inherit
with:
artifact-name-unsigned-rpms: ${{ env.ARTIFACT_NAME_RPM_UNSIGNED }}
artifact-name-signed-rpms: ${{ env.ARTIFACT_NAME_RPM_SIGNED }}
artifact-name-public-keys: ${{ env.ARTIFACT_NAME_GPG_KEYS_PUBLIC }}

release:
needs: rpmsign
uses: OpenCHAMI/github-actions/.github/workflows/release-signed-artifacts.yml@dev-rpm-quadlets
secrets: inherit
with:
artifact-name-signed-rpms: ${{ env.ARTIFACT_NAME_RPM_SIGNED }}
artifact-name-public-keys: ${{ env.ARTIFACT_NAME_GPG_KEYS_PUBLIC }}
25 changes: 24 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# SPDX-License-Identifier: MIT

.PHONY: help build test lint clean install run container-build container-run generate generate-check dev
.PHONY: help build test lint clean install run container-build container-run generate generate-check dev rpm-build rpm-clean

# Variables
BINARY_NAME=ochami-metadata
Expand All @@ -15,6 +15,12 @@ DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
CONTAINER_PROG ?= $(shell command -v docker 2>/dev/null)
CONTAINER_TAG ?= latest
CONTAINER_GO_VERSION ?= $(shell awk '/^go / {print $$2; exit}' go.mod)
# RPM version/release: strip the leading 'v' and rewrite git-describe's
# '-N-gHASH[-dirty]' suffix into RPM-legal dot separators (hyphens aren't
# allowed in an RPM Version field). An exact tag like v0.1.2 becomes 0.1.2.
RPM_VERSION ?= $(shell echo "$(VERSION)" | sed -e 's/^v//' -e 's/-/./g')
RPM_RELEASE ?= 1
RPM_TOPDIR ?= $(CURDIR)/dist/rpmbuild
LDFLAGS=-ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE)"
FABRICA_CMD ?= go run github.com/openchami/fabrica/cmd/fabrica@latest
FABRICA_SOURCE_ARG ?=
Expand Down Expand Up @@ -102,6 +108,23 @@ container-run: container-build ## Build and run Docker container
release-snapshot: ## Create a snapshot release with GoReleaser
goreleaser release --snapshot --clean

rpm-build: ## Build the metadata-service RPM (VERSION/RPM_RELEASE override the derived defaults)
@command -v rpmbuild >/dev/null 2>&1 || { echo "rpmbuild is required but not installed."; exit 1; }
rm -rf $(RPM_TOPDIR)
mkdir -p $(RPM_TOPDIR)/SOURCES/metadata-service-$(RPM_VERSION)/LICENSES
cp packaging/systemd/* $(RPM_TOPDIR)/SOURCES/metadata-service-$(RPM_VERSION)/
cp LICENSES/MIT.txt $(RPM_TOPDIR)/SOURCES/metadata-service-$(RPM_VERSION)/LICENSES/
tar -C $(RPM_TOPDIR)/SOURCES -czf $(RPM_TOPDIR)/SOURCES/metadata-service-$(RPM_VERSION).tar.gz \
metadata-service-$(RPM_VERSION)
rpmbuild --define "_topdir $(RPM_TOPDIR)" \
--define "version $(RPM_VERSION)" \
--define "rel $(RPM_RELEASE)" \
-bb packaging/metadata-service.spec
@echo "Built: $(RPM_TOPDIR)/RPMS/noarch/$$(ls $(RPM_TOPDIR)/RPMS/noarch)"

rpm-clean: ## Remove local RPM build artifacts
rm -rf $(RPM_TOPDIR)

fmt: ## Format code
$(GO) fmt ./...
goimports -w .
Expand Down
54 changes: 54 additions & 0 deletions packaging/metadata-service.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-FileCopyrightText: 2026 OpenCHAMI Contributors
# SPDX-License-Identifier: MIT
#
# See `make rpm-build` and docs/RPM_PACKAGING.md for the tag-to-version
# mapping and how the packaged quadlet's image tag is pinned to it.

Name: metadata-service
Version: %{version}
Release: %{rel}%{?dist}
Summary: OpenCHAMI metadata-service Quadlet units

License: MIT
URL: https://github.com/OpenCHAMI/metadata-service
Source0: %{name}-%{version}.tar.gz

BuildArch: noarch


# TODO: FIXME: metadata-service depends on smd and tokensmith, which do not
# exist as standalone RPMs yet.
# Requires: smd
# Requires: tokensmith
Requires: podman

%description
Podman Quadlet unit files (container + volume) for running metadata-service
as part of an OpenCHAMI deployment.

%prep
%setup -q

%install
mkdir -p %{buildroot}/usr/share/containers/systemd

sed "s|@IMAGE_TAG@|v%{version}|" metadata-service.container \
> %{buildroot}/usr/share/containers/systemd/metadata-service.container
chmod 644 %{buildroot}/usr/share/containers/systemd/metadata-service.container

install -m 644 metadata-data.volume \
%{buildroot}/usr/share/containers/systemd/metadata-data.volume


%files
%license LICENSES/MIT.txt
/usr/share/containers/systemd/metadata-service.container
/usr/share/containers/systemd/metadata-data.volume

%post
# reload systemd so the new Quadlet-generated unit is seen
systemctl daemon-reload

%postun
# reload systemd so the removed unit is dropped
systemctl daemon-reload
8 changes: 8 additions & 0 deletions packaging/systemd/metadata-data.volume
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-FileCopyrightText: 2026 OpenCHAMI Contributors
# SPDX-License-Identifier: MIT

[Unit]
Description=metadata-service Data Volume

[Volume]
VolumeName=metadata-service-data
Loading
Loading