feat(cozypkg): add cross-platform build targets with version injection

- Add pattern rule for building cozypkg binaries per platform
  (assets-cozypkg-<os>-<arch>) with checksums generation
- Add Version variable to cozypkg CLI injected via ldflags
- Split manifests into separate cozystack-crds.yaml and
  cozystack-operator.yaml files
- Update CI workflow to handle CRDs and operator as separate artifacts
- Update e2e tests and upload script for new manifest structure
- Suppress git describe stderr when no tags exist

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
This commit is contained in:
Andrei Kvapil 2026-01-15 15:50:30 +01:00
parent c3ccf5a0bc
commit 6dbfcbb93e
No known key found for this signature in database
GPG key ID: 931CF7FEACEAF765
7 changed files with 74 additions and 23 deletions

View file

@ -71,11 +71,17 @@ jobs:
name: pr-patch
path: _out/assets/pr.patch
- name: Upload installer
- name: Upload CRDs
uses: actions/upload-artifact@v4
with:
name: cozystack-installer
path: _out/assets/cozystack-installer.yaml
name: cozystack-crds
path: _out/assets/cozystack-crds.yaml
- name: Upload operator
uses: actions/upload-artifact@v4
with:
name: cozystack-operator
path: _out/assets/cozystack-operator.yaml
- name: Upload Talos image
uses: actions/upload-artifact@v4
@ -88,8 +94,9 @@ jobs:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'release')
outputs:
installer_id: ${{ steps.fetch_assets.outputs.installer_id }}
disk_id: ${{ steps.fetch_assets.outputs.disk_id }}
crds_id: ${{ steps.fetch_assets.outputs.crds_id }}
operator_id: ${{ steps.fetch_assets.outputs.operator_id }}
disk_id: ${{ steps.fetch_assets.outputs.disk_id }}
steps:
- name: Checkout code
@ -132,14 +139,16 @@ jobs:
return;
}
const find = (n) => draft.assets.find(a => a.name === n)?.id;
const installerId = find('cozystack-installer.yaml');
const diskId = find('nocloud-amd64.raw.xz');
if (!installerId || !diskId) {
const crdsId = find('cozystack-crds.yaml');
const operatorId = find('cozystack-operator.yaml');
const diskId = find('nocloud-amd64.raw.xz');
if (!crdsId || !operatorId || !diskId) {
core.setFailed('Required assets missing in draft release');
return;
}
core.setOutput('installer_id', installerId);
core.setOutput('disk_id', diskId);
core.setOutput('crds_id', crdsId);
core.setOutput('operator_id', operatorId);
core.setOutput('disk_id', diskId);
prepare_env:
@ -224,11 +233,18 @@ jobs:
run: mkdir -p _out/assets
# ▸ Regular PR path download artefacts produced by the *build* job
- name: "Download installer (regular PR)"
- name: "Download CRDs (regular PR)"
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
uses: actions/download-artifact@v4
with:
name: cozystack-installer
name: cozystack-crds
path: _out/assets
- name: "Download operator (regular PR)"
if: "!contains(github.event.pull_request.labels.*.name, 'release')"
uses: actions/download-artifact@v4
with:
name: cozystack-operator
path: _out/assets
# ▸ Release PR path fetch artefacts from the corresponding draft release
@ -237,8 +253,11 @@ jobs:
run: |
mkdir -p _out/assets
curl -sSL -H "Authorization: token ${GH_PAT}" -H "Accept: application/octet-stream" \
-o _out/assets/cozystack-installer.yaml \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/assets/${{ needs.resolve_assets.outputs.installer_id }}"
-o _out/assets/cozystack-crds.yaml \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/assets/${{ needs.resolve_assets.outputs.crds_id }}"
curl -sSL -H "Authorization: token ${GH_PAT}" -H "Accept: application/octet-stream" \
-o _out/assets/cozystack-operator.yaml \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/assets/${{ needs.resolve_assets.outputs.operator_id }}"
env:
GH_PAT: ${{ secrets.GH_PAT }}

View file

@ -37,11 +37,32 @@ build: build-deps
manifests:
mkdir -p _out/assets
(cd packages/core/installer/; helm template --namespace cozy-installer installer .) > _out/assets/cozystack-installer.yaml
helm template installer packages/core/installer -n cozy-system \
-s templates/crds.yaml \
> _out/assets/cozystack-crds.yaml
helm template installer packages/core/installer -n cozy-system \
-s templates/cozystack-operator.yaml \
-s templates/packagesource.yaml \
> _out/assets/cozystack-operator.yaml
assets:
cozypkg:
go build -ldflags "-X github.com/cozystack/cozystack/cmd/cozypkg/cmd.Version=v$(COZYSTACK_VERSION)" -o _out/bin/cozypkg ./cmd/cozypkg
assets: assets-talos assets-cozypkg
assets-talos:
make -C packages/core/talos assets
assets-cozypkg: assets-cozypkg-linux-amd64 assets-cozypkg-linux-arm64 assets-cozypkg-darwin-amd64 assets-cozypkg-darwin-arm64 assets-cozypkg-windows-amd64 assets-cozypkg-windows-arm64
(cd _out/assets/ && sha256sum cozypkg-*.tar.gz) > _out/assets/cozypkg-checksums.txt
assets-cozypkg-%:
$(eval EXT := $(if $(filter windows,$(firstword $(subst -, ,$*))),.exe,))
mkdir -p _out/assets
GOOS=$(firstword $(subst -, ,$*)) GOARCH=$(lastword $(subst -, ,$*)) go build -ldflags "-X github.com/cozystack/cozystack/cmd/cozypkg/cmd.Version=v$(COZYSTACK_VERSION)" -o _out/bin/cozypkg-$*/cozypkg$(EXT) ./cmd/cozypkg
cp LICENSE _out/bin/cozypkg-$*/LICENSE
tar -C _out/bin/cozypkg-$* -czf _out/assets/cozypkg-$*.tar.gz LICENSE cozypkg$(EXT)
test:
make -C packages/core/testing apply
make -C packages/core/testing test

View file

@ -23,6 +23,9 @@ import (
"github.com/spf13/cobra"
)
// Version is set at build time via -ldflags.
var Version = "dev"
// rootCmd represents the base command when called without any subcommands.
var rootCmd = &cobra.Command{
Use: "cozypkg",
@ -44,6 +47,6 @@ func Execute() error {
}
func init() {
// Commands are registered in their respective init() functions
rootCmd.Version = Version
}

View file

@ -1,8 +1,12 @@
#!/usr/bin/env bats
@test "Required installer assets exist" {
if [ ! -f _out/assets/cozystack-installer.yaml ]; then
echo "Missing: _out/assets/cozystack-installer.yaml" >&2
if [ ! -f _out/assets/cozystack-crds.yaml ]; then
echo "Missing: _out/assets/cozystack-crds.yaml" >&2
exit 1
fi
if [ ! -f _out/assets/cozystack-operator.yaml ]; then
echo "Missing: _out/assets/cozystack-operator.yaml" >&2
exit 1
fi
}
@ -12,7 +16,8 @@
kubectl create namespace cozy-system --dry-run=client -o yaml | kubectl apply -f -
# Apply installer manifests (CRDs + operator)
kubectl apply -f _out/assets/cozystack-installer.yaml
kubectl apply -f _out/assets/cozystack-crds.yaml
kubectl apply -f _out/assets/cozystack-operator.yaml
# Wait for the operator deployment to become available
kubectl wait deployment/cozystack-operator -n cozy-system --timeout=1m --for=condition=Available

View file

@ -3,9 +3,12 @@ set -xe
version=${VERSION:-$(git describe --tags)}
gh release upload --clobber $version _out/assets/cozystack-installer.yaml
gh release upload --clobber $version _out/assets/cozystack-crds.yaml
gh release upload --clobber $version _out/assets/cozystack-operator.yaml
gh release upload --clobber $version _out/assets/metal-amd64.iso
gh release upload --clobber $version _out/assets/metal-amd64.raw.xz
gh release upload --clobber $version _out/assets/nocloud-amd64.raw.xz
gh release upload --clobber $version _out/assets/kernel-amd64
gh release upload --clobber $version _out/assets/initramfs-metal-amd64.xz
gh release upload --clobber $version _out/assets/cozypkg-*.tar.gz
gh release upload --clobber $version _out/assets/cozypkg-checksums.txt

View file

@ -1,4 +1,3 @@
{{- range $path, $_ := .Files.Glob "definitions/*.yaml" }}
---
{{ $.Files.Get $path }}
{{- end }}

View file

@ -31,7 +31,8 @@ copy-nocloud-image:
docker cp ../../../_out/assets/nocloud-amd64.raw.xz "${SANDBOX_NAME}":/workspace/_out/assets/nocloud-amd64.raw.xz
copy-installer-manifest:
docker cp ../../../_out/assets/cozystack-installer.yaml "${SANDBOX_NAME}":/workspace/_out/assets/cozystack-installer.yaml
docker cp ../../../_out/assets/cozystack-crds.yaml "${SANDBOX_NAME}":/workspace/_out/assets/cozystack-crds.yaml
docker cp ../../../_out/assets/cozystack-operator.yaml "${SANDBOX_NAME}":/workspace/_out/assets/cozystack-operator.yaml
prepare-cluster: copy-nocloud-image
docker exec "${SANDBOX_NAME}" sh -c 'cd /workspace && hack/cozytest.sh hack/e2e-prepare-cluster.bats'