Skip to content

Commit

Permalink
Automate upstream bundle creation
Browse files Browse the repository at this point in the history
Add CI automation to create bundles for K8S and OKD

Removed "replaces" field from config as the field is only required in
OKD.
  • Loading branch information
clobrano committed Aug 1, 2024
1 parent b9371ce commit 34feda6
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 47 deletions.
48 changes: 10 additions & 38 deletions .github/workflows/post-submit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,26 @@ permissions:
pull-requests: read

jobs:
push-images:
name: Build and push images to quay.io/medik8s
push_to_registry:
name: Build and push unversioned images to quay.io/medik8s
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Log in to Quay.io
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
registry: quay.io

- name: Build and push CSV 0.0.1 + latest images for PR merges to main
if: ${{ github.ref_type != 'tag' }}
- name: Build and push CSV version 0.0.1 with latest images
run: export IMAGE_REGISTRY=quay.io/medik8s && make container-build-and-push-community

- name: Build and push versioned CSV and images for tags
if: ${{ github.ref_type == 'tag' }}
# remove leading 'v' from tag!
run: export VERSION=$(echo $GITHUB_REF_NAME | sed 's/v//') && make container-build-and-push-community

- name: Create release with manifests
if: ${{ github.ref_type == 'tag' }}
# https://github.com/marketplace/actions/github-release-create-update-and-upload-assets
uses: meeDamian/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
body: |
# Node Maintenance Operator ${{ github.ref_name }}
## Notable Changes
* TODO
## Release Artifacts
### Images
* Operator: quay.io/medik8s/node-maintenance-operator:${{ github.ref_name }}
* Bundle: quay.io/medik8s/node-maintenance-operator-bundle:${{ github.ref_name }}
* Catalog aka Index: quay.io/medik8s/node-maintenance-operator-catalog:${{ github.ref_name }}
### Source code and OLM manifests
Please find the source code and the OLM manifests in the `Assets` section below.
gzip: folders
files: >
Manifests:bundle/
107 changes: 107 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Release
on:
workflow_dispatch:
inputs:
operation:
description: "The operation to perform."
required: true
type: choice
default: "build_and_push_images"
options:
- build_and_push_images
- create_okd_release_pr
- create_k8s_release_pr
version:
description: "The version to release, without the leading `v`"
required: true
previous_version:
description: "The previous version, used for the CVS's `replaces` field, without the leading `v`"
required: true
ocp_version:
description: "The target OCP version for the release (mandatory for create_okd_release_pr option)"
required: false

permissions:
contents: write

jobs:
push_to_registry:
if: ${{ inputs.operation == 'build_and_push_images' }}
name: Build and push versioned images to quay.io/medik8s
runs-on: ubuntu-22.04
env:
VERSION: ${{ inputs.version }}
PREVIOUS_VERSION: ${{ inputs.previous_version }}
OCP_VERSION: ${{ inputs.ocp_version }}
steps:
- name: Log inputs
run: |
echo "Building version: ${VERSION},"
echo "which replaces version: ${PREVIOUS_VERSION}."
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Log in to Quay.io
uses: docker/login-action@v3
with:
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
registry: quay.io

- name: Build and push versioned CSV and images
run: VERSION=$VERSION PREVIOUS_VERSION=$PREVIOUS_VERSION make container-build-community container-push

- name: Create release with manifests, for tags
# https://github.com/marketplace/actions/github-release-create-update-and-upload-assets
uses: meeDamian/[email protected]
with:
tag: v${{ inputs.version }}
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
body: |
# Node Maintenance Operator ${{ inputs.version }}
## Notable Changes
* TODO
## Release Artifacts
### Images
* Operator: quay.io/medik8s/node-maintenance-operator:v${{ inputs.version }}
* Bundle: quay.io/medik8s/node-maintenance-operator-bundle:v${{ inputs.version }}
* Catalog aka Index: quay.io/medik8s/node-maintenance-operator-catalog:v${{ inputs.version }}
### Source code and OLM manifests
Please find the source code and the OLM manifests in the `Assets` section below.
gzip: folders
files: >
Manifests:bundle/
create_k8s_release_pr:
if: inputs.operation == 'create_k8s_release_pr'
uses: medik8s/.github/.github/workflows/release_community_bundle_parametric.yaml@main
secrets: inherit
with:
version: ${{ inputs.version }}
previous_version: ${{ inputs.previous_version }}
community: 'K8S'
make_targets: "bundle-community-k8s"
create_okd_release_pr:
if: inputs.operation == 'create_okd_release_pr'
uses: medik8s/.github/.github/workflows/release_community_bundle_parametric.yaml@main
secrets: inherit
with:
version: ${{ inputs.version }}
previous_version: ${{ inputs.previous_version }}
ocp_version: ${{ inputs.ocp_version }}
community: 'OKD'
make_targets: "bundle-community-okd"
60 changes: 52 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ GO_VERSION = 1.20
ENVTEST_K8S_VERSION = 1.28
# See https://github.com/slintes/sort-imports/releases for the last version
SORT_IMPORTS_VERSION = v0.2.1
# OCP Version: for OKD bundle community
OCP_VERSION ?= 4.12
# update for major version updates to YQ_VERSION! see https://github.com/mikefarah/yq
# NOTE: v4.42.1 is the latest supporting go 1.20
YQ_API_VERSION = v4
YQ_VERSION = v4.42.1

# IMAGE_REGISTRY used to indicate the registery/group for the operator, bundle and catalog
IMAGE_REGISTRY ?= quay.io/medik8s
Expand Down Expand Up @@ -212,29 +218,61 @@ export ICON_BASE64 ?= ${DEFAULT_ICON_BASE64}
export CSV ?= "./bundle/manifests/$(OPERATOR_NAME).clusterserviceversion.yaml"

.PHONY: bundle-update
bundle-update: verify-previous-version ## Update CSV fields and validate the bundle directory
bundle-update: ## Update CSV fields and validate the bundle directory
sed -r -i "s|containerImage: .*|containerImage: $(IMG)|;" ${CSV}
sed -r -i "s|createdAt: .*|createdAt: `date '+%Y-%m-%d %T'`|;" ${CSV}
sed -r -i "s|replaces: .*|replaces: $(OPERATOR_NAME).v${PREVIOUS_VERSION}|;" ${CSV}
sed -r -i "s|base64data:.*|base64data: ${ICON_BASE64}|;" ${CSV}
$(MAKE) bundle-validate

.PHONY: verify-previous-version
verify-previous-version: ## Verifies that PREVIOUS_VERSION variable is set
@if [ $(VERSION) != $(DEFAULT_VERSION) ] && [ $(VERSION) != $(CI_VERSION) ] && [ $(PREVIOUS_VERSION) = $(DEFAULT_VERSION) ]; then \
echo "Error: PREVIOUS_VERSION must be set for the selected VERSION"; \
exit 1; \
.PHONY: add-replaces-field
add-replaces-field: ## Add replaces field to the CSV
# add replaces field when building versioned bundle
@if [ $(VERSION) != $(DEFAULT_VERSION) ]; then \
if [ $(PREVIOUS_VERSION) == $(DEFAULT_VERSION) ]; then \
echo "Error: PREVIOUS_VERSION must be set for versioned builds"; \
exit 1; \
elif [ $(shell ./hack/semver_cmp.sh $(VERSION) $(PREVIOUS_VERSION)) != 1 ]; then \
echo "Error: VERSION ($(VERSION)) must be greater than PREVIOUS_VERSION ($(PREVIOUS_VERSION))"; \
exit 1; \
else \
# preferring sed here, in order to have "replaces" near "version" \
sed -r -i "/ version: $(VERSION)/ a\ replaces: $(OPERATOR_NAME).v$(PREVIOUS_VERSION)" ${CSV}; \
fi \
fi

.PHONY: bundle-reset-date
bundle-reset-date: ## Reset bundle's createdAt
sed -r -i "s|createdAt: .*|createdAt: \"\"|;" ${CSV}

.PHONY: bundle-community
bundle-community: bundle-k8s ## Update displayName, and description fields in the bundle's CSV
bundle-community: ## Update displayName, and description fields in the bundle's CSV
sed -r -i "s|displayName: Node Maintenance Operator|displayName: Node Maintenance Operator - Community Edition |;" ${CSV}
$(MAKE) bundle-update


.PHONY: bundle-community-k8s
bundle-community-k8s: bundle-k8s bundle-community ## Generate bundle manifests and metadata customized to Red Hat community release

.PHONY: bundle-community-okd
bundle-community-okd: bundle bundle-community ## Generate bundle manifests and metadata customized to Red Hat community release
$(MAKE) add-replaces-field
$(MAKE) add-ocp-annotations
echo -e "\n # Annotations for OCP\n com.redhat.openshift.versions: \"v${OCP_VERSION}\"" >> bundle/metadata/annotations.yaml


.PHONY: add-ocp-annotations
add-ocp-annotations: yq ## Add OCP annotations
$(YQ) -i '.metadata.annotations."operators.openshift.io/valid-subscription" = "[\"OpenShift Kubernetes Engine\", \"OpenShift Container Platform\", \"OpenShift Platform Plus\"]"' ${CSV}
# new infrastructure annotations see https://docs.engineering.redhat.com/display/CFC/Best_Practices#Best_Practices-(New)RequiredInfrastructureAnnotations
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/disconnected" = "true"' ${CSV}
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/fips-compliant" = "false"' ${CSV}
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/proxy-aware" = "false"' ${CSV}
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/tls-profiles" = "false"' ${CSV}
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/token-auth-aws" = "false"' ${CSV}
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/token-auth-azure" = "false"' ${CSV}
$(YQ) -i '.metadata.annotations."features.operators.openshift.io/token-auth-gcp" = "false"' ${CSV}


##@ Build

.PHONY: build
Expand Down Expand Up @@ -291,6 +329,7 @@ GINKGO_DIR ?= $(LOCALBIN)/ginkgo
OPM_DIR = $(LOCALBIN)/opm
OPERATOR_SDK_DIR ?= $(LOCALBIN)/operator-sdk
SORT_IMPORTS_DIR ?= $(LOCALBIN)/sort-imports
YQ_DIR ?= $(LOCALBIN)/yq

## Specific Tool Binaries
KUSTOMIZE = $(KUSTOMIZE_DIR)/$(KUSTOMIZE_VERSION)/kustomize
Expand All @@ -301,6 +340,7 @@ GINKGO = $(GINKGO_DIR)/$(GINKGO_VERSION)/ginkgo
OPM = $(OPM_DIR)/$(OPM_VERSION)/opm
OPERATOR_SDK = $(OPERATOR_SDK_DIR)/$(OPERATOR_SDK_VERSION)/operator-sdk
SORT_IMPORTS = $(SORT_IMPORTS_DIR)/$(SORT_IMPORTS_VERSION)/sort-imports
YQ = $(YQ_DIR)/$(YQ_API_VERSION)-$(YQ_VERSION)/yq

.PHONY: kustomize
kustomize: ## Download kustomize locally if necessary.
Expand All @@ -326,6 +366,10 @@ ginkgo: ## Download ginkgo locally if necessary.
sort-imports: ## Download sort-imports locally if necessary.
$(call go-install-tool,$(SORT_IMPORTS),$(SORT_IMPORTS_DIR),github.com/slintes/sort-imports@$(SORT_IMPORTS_VERSION))

.PHONY: yq
yq: ## Download yq locally if necessary.
$(call go-install-tool,$(YQ),$(YQ_DIR), github.com/mikefarah/yq/$(YQ_API_VERSION)@$(YQ_VERSION))

# go-install-tool will delete old package $2, then 'go install' any package $3 to $1.
define go-install-tool
@[ -f $(1) ]|| { \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,4 @@ spec:
provider:
name: Medik8s
url: https://github.com/medik8s
replaces: node-maintenance-operator.v0.0.1
version: 0.0.0
28 changes: 28 additions & 0 deletions hack/semver_cmp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# -*- coding: UTF-8 -*-
## Compare two semantic version numbers.
## semver_cmp.sh VER1 VER2 is equivalent to test if "VER1 >= VER2"
## Usage:
## - semver_cmp.sh 1.2.3 1.2.4 ## -1 VER1 is < than VER2
## - semver_cmp.sh 1.2.4 1.2.4 ## 0 VER1 is == to VER2
## - semver_cmp.sh 1.2.5 1.2.4 ## 1 VER1 is > than VER2
## other tests
## - semver_cmp.sh 1.2 1.2.4 ## -1
## - semver_cmp.sh 1.2 1.2 ## 0
## - semver_cmp.sh 1.3 1.2.9 ## 1

if [ "$#" -ne 2 ]; then
echo "Illegal number of parameters"
exit 1
fi

if [ "$1" = "$2" ]; then
echo 0
else
# sort the input and check if it is sorted (quietly).
# `sort` will exit successfully if the given file is already sorted, and exit with status 1 otherwise.
# Since we already excluded that the two versions are equal, if the input is sorted,
# it means the first argument is less than the second one.
# https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html#sort-invocation
printf "%s\n%s\n" "$1" "$2" | sort --version-sort --check=quiet && echo -1 || echo 1
fi

0 comments on commit 34feda6

Please sign in to comment.