Skip to content
Merged
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
159 changes: 159 additions & 0 deletions .github/workflows/build-push.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: Build (amd64 and arm64) and push to quay registries
on:
push:
branches: ["main"]
tags: ['[0-9]+.[0-9]+.[0-9]+']
pull_request:
branches: ["main"]

workflow_dispatch:

permissions:
contents: read

env:
REGISTRY: localhost
NAME: patterns-operator
TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || (github.ref_name == 'main' && 'latest' || github.ref_name) }}

jobs:
build-container:
strategy:
matrix:
include:
- targetarch: amd64
runner: ubuntu-latest
- targetarch: arm64
runner: ubuntu-24.04-arm

runs-on: ${{ matrix.runner }}
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Build container and save tarball
env:
TARGETARCH: ${{ matrix.targetarch }}
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
KEY: ${{ secrets.API_KEY }}
run: |
export APIFILE="internal/controller/apikey.txt"
trap "rm -f ${APIFILE}" SIGINT EXIT

if [ -z "${KEY}" ]; then
echo "Key is empty"
echo '' > "${APIFILE}"
else
echo "Key is set"
echo "${KEY}" > "${APIFILE}"
fi
make "podman-build-${TARGETARCH}"
buildah push "${OPERATOR_IMG}-${TARGETARCH}" "docker-archive:/tmp/image-${TARGETARCH}.tar:${OPERATOR_IMG}-${TARGETARCH}"

- name: Upload image artifact
uses: actions/upload-artifact@v4
with:
name: image-${{ matrix.targetarch }}-${{ github.run_id }}
path: /tmp/image-${{ matrix.targetarch }}.tar
retention-days: 1

pre-push-check:
needs: [build-container]
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
persist-credentials: false

# We use an env due to https://docs.zizmor.sh/audits/#remediation_18
- name: Check that tag version corresponds to metadata version
run: |-
VERSION=$(yq -r '.spec.version' bundle/manifests/patterns-operator.clusterserviceversion.yaml)
if [ "${VERSION}" != "${TAG}" ]; then
echo "Version in metadata ${VERSION} whereas tag is different: ${TAG}"
exit 1
fi

push-multiarch-manifest:
needs: [pre-push-check]
if: github.event_name != 'pull_request'
strategy:
matrix:
include:
- upload_registry: quay.io/validatedpatterns
legacy: false
- upload_registry: quay.io/hybridcloudpatterns
legacy: true
runs-on: ubuntu-latest
permissions:
contents: read
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Download AMD64 image
uses: actions/download-artifact@v5
with:
name: image-amd64-${{ github.run_id }}
path: /tmp

- name: Download ARM64 image
uses: actions/download-artifact@v5
with:
name: image-arm64-${{ github.run_id }}
path: /tmp

- name: Load tarballs into local containers-storage
run: |
buildah pull docker-archive:/tmp/image-amd64.tar
buildah pull docker-archive:/tmp/image-arm64.tar

- name: Log into Quay
env:
USERNAME: ${{ matrix.legacy && secrets.LEGACY_QUAY_USERNAME || secrets.QUAY_USERNAME }}
PASSWORD: ${{ matrix.legacy && secrets.LEGACY_QUAY_PASSWORD || secrets.QUAY_PASSWORD }}
run: |
buildah login -u "${USERNAME}" -p "${PASSWORD}" quay.io

# The compressed manifest in Quay has a different digest than the local so we
# need to use skopeo to retrieve the correct digest for signing
- name: Create manifest and push to Quay
id: manifest-push
env:
UPLOADREGISTRY: ${{ matrix.upload_registry }}
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
run: |
make buildah-manifest
buildah manifest add --arch=amd64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-amd64"
buildah manifest add --arch=arm64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-arm64"
make buildah-push
DIGEST=$(skopeo inspect --format "{{.Digest}}" "docker://${UPLOADREGISTRY}/${OPERATOR_IMG}")
echo "digest=$DIGEST" >> "$GITHUB_OUTPUT"

- name: Install cosign
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
with:
cosign-release: "v2.2.4"

# Cosign expects the docker config.json for registry authentication so we must
# copy it from buildah
- name: Sign the published Docker image
env:
DIGEST: ${{ steps.manifest-push.outputs.digest }}
UPLOADREGISTRY: ${{ matrix.upload_registry }}
OPERATOR_IMG: ${{ env.NAME }}:${{ env.TAG }}
run: |
cat "${XDG_RUNTIME_DIR}/containers/auth.json" > ~/.docker/config.json
cosign sign --yes "${UPLOADREGISTRY}/${OPERATOR_IMG}@${DIGEST}"
33 changes: 0 additions & 33 deletions .github/workflows/docker-build.yml

This file was deleted.

68 changes: 0 additions & 68 deletions .github/workflows/push-built-tag.yml

This file was deleted.

24 changes: 7 additions & 17 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS builder
RUN microdnf install git-core jq tar -y && microdnf clean all
ARG GO_VERSION=1.24.6
FROM registry.access.redhat.com/ubi9/go-toolset:${GO_VERSION} AS builder
ARG GOARCH=amd64

# Build the manager binary

Expand All @@ -9,18 +10,6 @@ WORKDIR /workspace
COPY go.mod go.mod
COPY go.sum go.sum

# use latest Go z release
ENV GOTOOLCHAIN=auto
ENV GO_INSTALL_DIR=/golang

# Ensure correct Go version
RUN export GO_VERSION=$(grep -E "go [[:digit:]]\.[[:digit:]][[:digit:]]" go.mod | awk '{print $2}') && \
export GO_FILENAME=$(curl -sL 'https://go.dev/dl/?mode=json&include=all' | jq -r "[.[] | select(.version | startswith(\"go${GO_VERSION}\"))][0].files[] | select(.os == \"linux\" and .arch == \"amd64\") | .filename") && \
curl -sL -o go.tar.gz "https://golang.org/dl/${GO_FILENAME}" && \
mkdir -p ${GO_INSTALL_DIR} && \
tar -C ${GO_INSTALL_DIR} -xzf go.tar.gz && \
rm go.tar.gz && ln -sf ${GO_INSTALL_DIR}/go/bin/go /usr/bin/go

# Copy the go sources
COPY vendor/ vendor/
COPY cmd/main.go cmd/main.go
Expand All @@ -29,11 +18,12 @@ COPY version/ version/
COPY internal/controller/ internal/controller/
COPY hack/ hack/
COPY .git/ .git/
RUN mkdir /licenses
COPY LICENSE /licenses
COPY LICENSE /licenses/
COPY Makefile .

# Build
RUN --mount=type=secret,id=apikey hack/build.sh
USER root
RUN --mount=type=secret,id=apikey GOARCH=${GOARCH} make build

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
Expand Down
39 changes: 33 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ VERSION ?= 0.0.4
OPERATOR_NAME ?= patterns
GOFLAGS=-mod=vendor
GOLANGCI_VERSION ?= 2.5.0
REGISTRY ?= localhost
UPLOADREGISTRY ?= quay.io/validatedpatterns

# CI uses a non-writable home dir, make sure .cache is writable
ifeq ("${HOME}", "/")
Expand Down Expand Up @@ -65,6 +67,7 @@ BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)

# Image URL to use all building/pushing image targets
IMG ?= $(IMAGE_TAG_BASE):$(VERSION)
OPERATOR_IMG ?= $(OPERATOR_NAME)-operator:$(VERSION)
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.30

Expand Down Expand Up @@ -148,18 +151,42 @@ clean: ## Remove build artifacts and downloaded tools
run: apikey manifests generate fmt vet ## Run a controller from your host.
GOOS=${GOOS} GOARCH=${GOARCH} hack/build.sh run

.PHONY: docker-build
docker-build: apikey ## Build docker image with the manager.
docker build --secret id=apikey,src=$(APIKEYFILE) --platform $(CONTAINER_OS)/$(CONTAINER_PLATFORM) -t ${IMG} .

.PHONY: docker-push
docker-push: ## Push docker image with the manager.
docker push ${IMG}
##@ Conatiner-related tasks
.PHONY: buildah-manifest
buildah-manifest: apikey ## creates the buildah manifest for multi-arch images
# The rm is needed due to bug https://www.github.com/containers/podman/issues/19757
buildah manifest rm "${REGISTRY}/${OPERATOR_IMG}" || /bin/true
buildah manifest create "${REGISTRY}/${OPERATOR_IMG}"

.PHONY: podman-build-amd64
podman-build-amd64: buildah-manifest ## build the container in amd64
@echo "Building the operator amd64"
buildah build --secret id=apikey,src=$(APIKEYFILE) --platform linux/amd64 --format docker -f Dockerfile -t "${OPERATOR_IMG}-amd64"
buildah manifest add --arch=amd64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-amd64"

.PHONY: podman-build-arm64
podman-build-arm64: buildah-manifest ## build the container in arm64
@echo "Building the operator arm64"
buildah build --secret id=apikey,src=$(APIKEYFILE) --platform linux/arm64 --build-arg GOARCH="arm64" --format docker -f Dockerfile -t "${OPERATOR_IMG}-arm64"
buildah manifest add --arch=arm64 "${REGISTRY}/${OPERATOR_IMG}" "${REGISTRY}/${OPERATOR_IMG}-arm64"

.PHONY: buildah-push
buildah-push: ## Uploads the container to quay.io/validatedpatterns/${OPERATOR_IMG}
@echo "Uploading the ${REGISTRY}/${OPERATOR_IMG} container to ${UPLOADREGISTRY}/${OPERATOR_IMG}"
buildah manifest push --all "${REGISTRY}/${OPERATOR_IMG}" "docker://${UPLOADREGISTRY}/${OPERATOR_IMG}"

.PHONY: golangci-lint
golangci-lint: apikey ## Run golangci-lint locally
podman run --pull=newer --rm -v $(PWD):/app:rw,z -w /app golangci/golangci-lint:v$(GOLANGCI_VERSION) golangci-lint run -v

##@ Legacy docker tasks
.PHONY: docker-build
docker-build: apikey podman-build-amd64 ## Build docker image with the manager.

.PHONY: docker-push
docker-push: buildah-push ## Push docker image with the manager.

##@ Deployment

ifndef ignore-not-found
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ metadata:
operators.openshift.io/must-gather-image: quay.io/validatedpatterns/must-gather:latest
repository: https://github.com/validatedpatterns/patterns-operator
support: validatedpatterns@googlegroups.com
labels:
operatorframework.io/arch.amd64: supported
operatorframework.io/arch.arm64: supported
name: patterns-operator.v0.0.0
namespace: placeholder
spec:
Expand Down
5 changes: 0 additions & 5 deletions hack/build.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
#!/bin/bash
set -ex

# GOOS and GOARCH will be set if calling from make. Dockerfile calls this script
# directly without calling make so the default values need to be set here also.
[[ -z "$GOOS" ]] && GOOS=linux
[[ -z "$GOARCH" ]] && GOARCH=amd64

GIT_VERSION=$(git describe --always --tags || true)
VERSION=${CI_UPSTREAM_VERSION:-${GIT_VERSION}}
GIT_COMMIT=$(git rev-list -1 HEAD || true)
Expand Down