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
16 changes: 15 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,23 @@ jobs:

olm:
name: OLM Bundle & Catalog
needs:
- change-triage
- core
- operator
# the bundle needs the core and operator images

if: |
!cancelled() &&
(needs.change-triage.outputs.operator-changed == 'true' ||
needs.change-triage.outputs.run-openshift == 'true') &&
needs.operator.result == 'success' &&
(needs.core.result == 'success' || needs.core.result == 'skipped')
env:
# The OpenShift Catalog is just for internal testing purpose until it won't.
ENVIRONMENT: "testing"
SKIP_IMAGE_DIGESTS: >-
${{ (needs.change-triage.outputs.core-changed != 'true' &&
needs.change-triage.outputs.run-openshift != 'true') && 'true' || '' }}
runs-on: ubuntu-24.04
permissions:
contents: read
Expand Down
130 changes: 130 additions & 0 deletions .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,133 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
task all:publish

check-release:
name: Evaluate the release tag
needs:
- release-publish
if: github.repository_owner == 'cloudnative-pg'
runs-on: ubuntu-24.04
permissions:
contents: read
outputs:
is-latest: ${{ steps.check.outputs.is-latest }}
steps:
- name: Check whether this is the newest release
id: check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.event.release.tag_name }}
run: |
latest=$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" \
--jq '.tag_name' 2>/dev/null || true)
is_latest="false"
if [ "${latest}" = "${TAG}" ]; then
is_latest="true"
fi
echo "is-latest=${is_latest}" >> "${GITHUB_OUTPUT}"
echo "Release ${TAG} is-latest=${is_latest} (latest is ${latest})"

olm-bundle:
name: Build and push the OLM bundle and catalog
needs:
- release-publish
- check-release
if: needs.check-release.outputs.is-latest == 'true'
env:
ENVIRONMENT: "production"
runs-on: ubuntu-24.04
permissions:
contents: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0

- name: Cleanup disk
uses: ./.github/actions/cleanup-disk

- name: Setup dagger
uses: ./.github/actions/setup-dagger

- name: Login to ghcr.io using Podman
uses: redhat-actions/podman-login@50c2d9a331bb67c8fdab99b86455fad05e2e3252 # v2
with:
registry: "ghcr.io"
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push the bundle and catalog
run: |
task olm:publish

- name: Upload the bundle
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: bundle
path: operator/bundle

- name: Attach the CatalogSource manifest to the release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.event.release.tag_name }}
run: |
gh release upload "${TAG}" operator/klio-operator-catalog-source.yaml \
--repo "${GITHUB_REPOSITORY}" --clobber

publish-bundle:
name: Publish the OLM bundle to the artifacts repository
needs:
- olm-bundle
env:
VERSION: ${{ github.event.release.tag_name }}
BUNDLE_DIR: klio/bundles
concurrency:
group: publish-bundle
cancel-in-progress: false
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- name: Checkout the artifacts repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
repository: cloudnative-pg/artifacts
token: ${{ secrets.REPO_GHA_PAT }}
ref: main
fetch-depth: 0

- name: Configure the git user
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR_ID}+${GITHUB_ACTOR}@users.noreply.github.com"

- name: Download the bundle
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: bundle
path: downloaded-bundle

- name: Copy the bundle
run: |
target="${BUNDLE_DIR}/${VERSION#v}"
rm -rf "${target}"
mkdir -p "${target}"
cp -R downloaded-bundle/* "${target}"
rm -rf downloaded-bundle

- name: Commit and push the bundle
run: |
if [ -z "$(git status --porcelain)" ]; then
echo "Bundle for ${VERSION#v} is already up to date"
exit 0
fi
git add "${BUNDLE_DIR}/${VERSION#v}"
git commit -sm "klio-operator (${VERSION#v})"
# The checkout above persisted REPO_GHA_PAT, so no separate push
# action is needed. Rebase first: the artifacts repository is shared
# with the other CloudNativePG projects and main may have moved.
git pull --rebase origin main
git push origin HEAD:main
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ bundle/
operator/olm-manifests/
operator/config/manifest-build/
operator/config/olm-default/manager_sidecar_image_patch.yaml
operator/config/manifests/csv_container_image_patch.yaml
operator/config/manifests/csv_skip_range_patch.yaml
operator/config/manifests/sample_image_patch.yaml
operator/catalog
operator/catalog.Dockerfile
operator/klio-operator-template.yaml
Expand Down
108 changes: 107 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ vars:
# image, since that is the variant submitted to Red Hat certification.
UBI_TAG_SUFFIX: '-ubi9'
ALLOWED_ENVS: [testing, production]
# OLM channel the bundle is published on. "stable" is the support tier and
# "v0" pins the major version, per the OLM channel-naming convention
# (https://olm.operatorframework.io/docs/best-practices/channel-naming/).
# Bump to stable-v1 at the 1.0 release, by adding the new channel instead
# of renaming this one.
OLM_CHANNELS: 'stable-v0'
OLM_DEFAULT_CHANNEL: 'stable-v0'
# Minimum OpenShift version the bundle declares support for
OPENSHIFT_VERSIONS: 'v4.14'
# First release that ships an OLM bundle. It is the lower bound of the CSV's
# olm.skipRange, which is what lets a catalog carrying a single bundle still
# offer an upgrade from any earlier release (see olm:manifest). Never lower
# it, and only raise it if a version range is ever declared unupgradable.
OLM_FIRST_BUNDLE_VERSION: '0.0.21'
# Set to a non-empty value to build the OLM bundle without pinning images to
# digests. Defaults to empty, so digest pinning is on wherever it can work;
# see olm:bundle for when CI turns it off.
SKIP_IMAGE_DIGESTS: '{{ .SKIP_IMAGE_DIGESTS | default "" }}'

tasks:

Expand Down Expand Up @@ -754,13 +772,39 @@ tasks:
# registry and tag, differing only by the "klio" repository instead of
# "klio-operator". The patch is consumed by
# operator/config/olm-default/kustomization.yaml.
#
# RELATED_IMAGE_SIDECAR carries the same value under the name OLM
# tooling recognizes: operator-sdk's --use-image-digests only discovers
# container images and RELATED_IMAGE_* env vars,
- |
cat > operator/config/olm-default/manager_sidecar_image_patch.yaml <<EOF
- op: add
path: /spec/template/spec/containers/0/env
value:
- name: SIDECAR_IMAGE
value: ${registry}/klio${suffix}:${tag}
- name: RELATED_IMAGE_SIDECAR
value: ${registry}/klio${suffix}:${tag}
EOF
- |
cat > operator/config/manifests/csv_container_image_patch.yaml <<EOF
- op: add
path: /metadata/annotations/containerImage
value: ${registry}/klio-operator${suffix}:${tag}${ubi_suffix}
EOF
# Declare the range of already-released versions this bundle can be
# installed over, as olm.skipRange.
- |
cat > operator/config/manifests/csv_skip_range_patch.yaml <<EOF
- op: add
path: /metadata/annotations/olm.skipRange
value: ">={{ .OLM_FIRST_BUNDLE_VERSION }} <{{ .GIT_TAG_VERSION }}"
EOF
- |
cat > operator/config/manifests/sample_image_patch.yaml <<EOF
- op: add
path: /spec/image
value: ${registry}/klio${suffix}:${tag}
EOF
- >
GITHUB_REF= dagger -s call -m github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA}
Expand All @@ -780,9 +824,31 @@ tasks:

olm:bundle:
desc: Generate the OLM bundle for the operator
summary: |
Note that --use-image-digests makes operator-sdk resolve every image in
the CSV against its registry, so the operator image for this ref must
already be pushed when this runs. Callers must therefore order themselves
after the operator build (in CI, the olm job needs the operator job).

Digest pinning is enabled only when running in GitHub Actions, where the
images live on ghcr.io.

Resolution covers *every* image in the CSV, the operand included, so a
caller that cannot guarantee the operand image was pushed for this ref
must set SKIP_IMAGE_DIGESTS. The CI olm job does that on pull requests
where the core job is skipped; releases always build both, and never set
it.

run: once
requires:
vars:
- name: ENVIRONMENT
enum:
ref: .ALLOWED_ENVS
deps:
- olm:manifest
env:
use_image_digests: '{{ if and .GITHUB_ACTIONS (not .SKIP_IMAGE_DIGESTS) }}--use-image-digests{{ end }}'
cmds:
- >
docker
Expand All @@ -794,11 +860,20 @@ tasks:
generate bundle
--input-dir olm-manifests/
--kustomize-dir config/manifests
--package klio-operator
--channels {{ .OLM_CHANNELS }}
--default-channel {{ .OLM_DEFAULT_CHANNEL }}
${use_image_digests}
--version {{ .GIT_TAG_VERSION }}
- |
printf '\n # OpenShift annotations.\n com.redhat.openshift.versions: "%s"\n' \
'{{ .OPENSHIFT_VERSIONS }}' >> operator/bundle/metadata/annotations.yaml
printf '\n# OpenShift labels.\nLABEL com.redhat.openshift.versions="%s"\n' \
'{{ .OPENSHIFT_VERSIONS }}' >> operator/bundle.Dockerfile
sources:
- operator/olm-manifests/**
generates:
- bundle/
- operator/bundle/**

olm:build:
desc: Build the require OLM bundle image after generating the bundle
Expand Down Expand Up @@ -941,6 +1016,37 @@ tasks:
image: ${registry}/klio-operator${suffix}:${tag}-catalog
EOF

olm:publish:
desc: Publish the OLM bundle and catalog images for a release
summary: |
Release counterpart of olm:all. Builds and pushes the production bundle
and catalog images (no "-testing" suffix) for the tag being released, and
leaves operator/bundle/ on disk for the release workflow to upload and
forward to the artifacts repository.

Scorecard is deliberately not re-run here: it already ran against the
same bundle in the CI olm job, and it needs a k3s-capable engine that the
release runner is not set up for.
requires:
# We expect this to run in a GitHub workflow, so we put a few
# GitHub-specific vars here to prevent running this task locally by
# accident.
vars:
- CI
- GITHUB_REPOSITORY
- GITHUB_REF
- GITHUB_REF_NAME
preconditions:
- sh: "[[ {{.GITHUB_REF}} =~ 'refs/tags/v.*' ]]"
msg: not a tag, failing
- sh: '[[ "{{ .GIT_TAG_VERSION }}" == "{{ trimPrefix "v" .GITHUB_REF_NAME }}" ]]'
msg: >-
bundle version {{ .GIT_TAG_VERSION }} does not match tag
{{ .GITHUB_REF_NAME }}; refusing to publish an inconsistent bundle
cmds:
- task: olm:catalog
- task: olm:catalog-source

olm:preflight-container:
desc: Run Red Hat Preflight (check container) certification on the operator image
dir: operator
Expand Down
3 changes: 3 additions & 0 deletions documentation/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CRC
CRC's
CRDs
CSV
CSV's
CatalogSource
CheckpointTime
ClientCASecretName
Expand Down Expand Up @@ -290,6 +291,7 @@ pre
prefetch
prefetching
preflight
prereleases
priorityClassName
prometheus
proto
Expand Down Expand Up @@ -319,6 +321,7 @@ uint
ulong
unicode
unreferenced
unupgradable
uptime
verifications
wal
Expand Down
Loading
Loading