continuous-integration #3023
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This workflow executes the following actions: | |
# - Runs Golang and ShellCheck linters | |
# - Runs Unit tests | |
# - Verifies API doc and CRDs are up to date | |
# - Builds the operator image (no push) | |
name: continuous-integration | |
on: | |
push: | |
branches: | |
- main | |
- release-* | |
pull_request: | |
workflow_dispatch: | |
schedule: | |
- cron: '0 1 * * *' | |
# set up environment variables to be used across all the jobs | |
env: | |
GOLANG_VERSION: "1.23.x" | |
GOLANGCI_LINT_VERSION: "v1.61.0" | |
KUBEBUILDER_VERSION: "2.3.1" | |
KIND_VERSION: "v0.24.0" | |
OPERATOR_IMAGE_NAME: "ghcr.io/${{ github.repository }}-testing" | |
API_DOC_NAME: "cloudnative-pg.v1.md" | |
SLACK_USERNAME: "cnpg-bot" | |
# Keep in mind that adding more platforms (architectures) will increase the building | |
# time even if we use the ghcache for the building process. | |
PLATFORMS: "linux/amd64,linux/arm64" | |
BUILD_PUSH_PROVENANCE: "" | |
BUILD_PUSH_CACHE_FROM: "" | |
BUILD_PUSH_CACHE_TO: "" | |
BUILD_PLUGIN_RELEASE_ARGS: "build --skip=validate --clean --id kubectl-cnpg --timeout 60m" | |
BUILD_MANAGER_RELEASE_ARGS: "build --skip=validate --clean --id manager" | |
REPOSITORY_OWNER: "cloudnative-pg" | |
REGISTRY: "ghcr.io" | |
REGISTRY_USER: ${{ github.actor }} | |
REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
OPP_SCRIPT_URL: "https://raw.githubusercontent.com/redhat-openshift-ecosystem/community-operators-pipeline/ci/latest/ci/scripts/opp.sh" | |
defaults: | |
run: | |
# default failure handling for shell scripts in 'run' steps | |
shell: 'bash -Eeuo pipefail -x {0}' | |
jobs: | |
# Trigger the workflow on release-* branches for smoke testing whenever it's a scheduled run. | |
# Note: this is a workaround since we can't directly schedule-run a workflow from a non default branch | |
smoke_test_release_branches: | |
runs-on: ubuntu-24.04 | |
name: smoke test release-* branches when it's a scheduled run | |
if: github.event_name == 'schedule' | |
strategy: | |
fail-fast: false | |
matrix: | |
branch: [release-1.22, release-1.23, release-1.24] | |
steps: | |
- name: Invoke workflow with inputs | |
uses: benc-uk/workflow-dispatch@v1 | |
with: | |
workflow: continuous-integration | |
ref: ${{ matrix.branch }} | |
# Detects if we should skip the workflow due to being duplicated. Exceptions: | |
# 1. it's on 'main' branch | |
# 2. it's triggered by events in the 'do_not_skip' list | |
duplicate_runs: | |
runs-on: ubuntu-24.04 | |
name: Skip duplicate runs | |
continue-on-error: true | |
outputs: | |
should_skip: ${{ steps.skip_check.outputs.should_skip == 'true' && github.ref != 'refs/heads/main' }} | |
steps: | |
- id: skip_check | |
uses: fkirc/[email protected] | |
with: | |
concurrent_skipping: 'same_content' | |
skip_after_successful_duplicate: 'true' | |
paths_ignore: '["README.md", "docs/**"]' | |
do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' | |
# Classify codebase changes along 5 different dimensions based on the files | |
# changed in the commit/PR, and create 5 different filters which are used in | |
# the following jobs to decide whether the step should be skipped. | |
change-triage: | |
name: Check changed files | |
needs: duplicate_runs | |
if: ${{ needs.duplicate_runs.outputs.should_skip != 'true' }} | |
runs-on: ubuntu-24.04 | |
outputs: | |
docs-changed: ${{ steps.filter.outputs.docs-changed }} | |
operator-changed: ${{ steps.filter.outputs.operator-changed }} | |
test-changed: ${{ steps.filter.outputs.test-changed }} | |
shell-script-changed: ${{ steps.filter.outputs.shell-script-changed }} | |
go-code-changed: ${{ steps.filter.outputs.go-code-changed }} | |
renovate-changed: ${{ steps.filter.outputs.renovate-changed }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Check for changes | |
uses: dorny/[email protected] | |
id: filter | |
# Remember to add new folders in the operator-changed filter if needed | |
with: | |
base: ${{ (github.event_name == 'schedule') && 'main' || '' }} | |
filters: | | |
docs-changed: | |
- '**/*.md' | |
- 'docs/**' | |
- '.wordlist-en-custom.txt' | |
operator-changed: | |
- 'api/**' | |
- 'cmd/**' | |
- 'config/**' | |
- 'internal/**' | |
- 'licenses/**' | |
- 'pkg/**' | |
- '.github/workflows/continuous-delivery.yml' | |
- '.github/workflows/continuous-integration.yml' | |
- '.goreleaser*.yml' | |
- 'Dockerfile' | |
- 'Dockerfile-ubi8' | |
- 'Dockerfile-ubi9' | |
- 'Makefile' | |
- 'go.mod' | |
- 'go.sum' | |
test-changed: | |
- '.github/e2e-matrix-generator.py' | |
- '.github/generate-test-artifacts.py' | |
- 'tests/**' | |
- 'hack/**' | |
shell-script-changed: | |
- '**/*.sh' | |
go-code-changed: | |
- '**/*.go' | |
- '.golangci.yml' | |
renovate-changed: | |
- '.github/renovate.json5' | |
go-linters: | |
name: Run linters | |
needs: | |
- duplicate_runs | |
- change-triage | |
# We need always run linter as go linter is a required check | |
if: needs.duplicate_runs.outputs.should_skip != 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
# Disable setup-go caching. Cache is better handled by the golangci-lint action | |
cache: false | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Run golangci-lint | |
uses: golangci/golangci-lint-action@v6 | |
with: | |
version: ${{ env.GOLANGCI_LINT_VERSION }} | |
- name: Check go mod tidy has no pending changes | |
run: | | |
make go-mod-check | |
renovate-linter: | |
name: Renovate Linter | |
needs: | |
- duplicate_runs | |
- change-triage | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
needs.change-triage.outputs.renovate-changed == 'true' | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Validate Renovate JSON | |
run: npx --yes --package renovate -- renovate-config-validator | |
go-vulncheck: | |
name: Run govulncheck | |
needs: | |
- duplicate_runs | |
- change-triage | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
( | |
needs.change-triage.outputs.operator-changed == 'true' || | |
needs.change-triage.outputs.go-code-changed == 'true' | |
) | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Run govulncheck | |
uses: golang/govulncheck-action@v1 | |
with: | |
go-version-input: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
shellcheck: | |
name: Run shellcheck linter | |
needs: | |
- duplicate_runs | |
- change-triage | |
# Run shellcheck linter only if shell code has changed | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
needs.change-triage.outputs.shell-script-changed == 'true' | |
runs-on: ubuntu-24.04 | |
env: | |
SHELLCHECK_OPTS: -a -S style | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Run ShellCheck | |
uses: ludeeus/[email protected] | |
generate-unit-tests-jobs: | |
name: Generate jobs for unit tests | |
needs: | |
- duplicate_runs | |
- change-triage | |
# Generate unit tests jobs only if the operator or the Go codebase have changed | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
( | |
needs.change-triage.outputs.operator-changed == 'true' || | |
needs.change-triage.outputs.go-code-changed == 'true' | |
) | |
runs-on: ubuntu-24.04 | |
outputs: | |
k8sMatrix: ${{ steps.get-k8s-versions.outputs.k8s_versions }} | |
latest_k8s_version: ${{ steps.get-k8s-versions.outputs.latest_k8s_version }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Get k8s versions for unit test | |
id: get-k8s-versions | |
shell: bash | |
run: | | |
k8s_versions=$(jq -c ' | |
.unit_test.max as $max | | |
.unit_test.min as $min | | |
$min | [ while(. <= $max; | |
. | split(".") | .[1] |= (.|tonumber|.+1|tostring) | join(".") | |
) | |
] | | |
.[] |= .+".x" | |
' < .github/k8s_versions_scope.json) | |
echo "k8s_versions=${k8s_versions}" >> $GITHUB_OUTPUT | |
latest_k8s_version=$(jq -r '.|last' <<< $k8s_versions) | |
echo "latest_k8s_version=${latest_k8s_version}" >> $GITHUB_OUTPUT | |
tests: | |
name: Run unit tests | |
needs: | |
- duplicate_runs | |
- change-triage | |
- generate-unit-tests-jobs | |
# Run unit tests only if the operator or the Go codebase have changed | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
( | |
needs.change-triage.outputs.operator-changed == 'true' || | |
needs.change-triage.outputs.go-code-changed == 'true' | |
) | |
runs-on: ubuntu-24.04 | |
strategy: | |
matrix: | |
# The Unit test is performed per multiple supported k8s versions (each job for each k8s version) as below: | |
k8s-version: ${{ fromJSON(needs.generate-unit-tests-jobs.outputs.k8sMatrix) }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Run unit tests | |
env: | |
ENVTEST_K8S_VERSION: ${{ matrix.k8s-version }} | |
run: | | |
make test | |
- name: Coverage Summary | |
if: matrix.k8s-version == needs.generate-unit-tests-jobs.outputs.latest_k8s_version | |
run: | | |
go tool cover -func=cover.out -o coverage.out | |
- name: Publish unit test summary on the latest k8s version | |
if: matrix.k8s-version == needs.generate-unit-tests-jobs.outputs.latest_k8s_version | |
run: | | |
echo "Unit test coverage: $(tail -n 1 coverage.out | awk '{print $3}')" >> $GITHUB_STEP_SUMMARY | |
apidoc: | |
name: Verify API doc is up to date | |
needs: | |
- duplicate_runs | |
- change-triage | |
# Run make apidoc if Go code or docs have changed | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
( | |
needs.change-triage.outputs.go-code-changed == 'true' || | |
needs.change-triage.outputs.docs-changed == 'true' | |
) | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Run make apidoc | |
run: | | |
make apidoc | |
- name: Verify apidoc changes | |
run: | | |
apidoc_file_path='docs/src/${{ env.API_DOC_NAME }}' | |
if git status --porcelain $apidoc_file_path | grep '^ M'; then | |
echo "The API documentation doesn't reflect the current API. Please run make apidoc." | |
exit 1 | |
fi | |
crd: | |
name: Verify CRD is up to date | |
needs: | |
- duplicate_runs | |
- change-triage | |
# Run make manifests if Go code have changed | |
if: | | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
( | |
needs.change-triage.outputs.go-code-changed == 'true' || | |
needs.change-triage.outputs.operator-changed == 'true' | |
) | |
runs-on: ubuntu-24.04 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Run make manifests | |
run: | | |
make manifests | |
- name: Check CRD manifests are up to date | |
run: | | |
crd_path='config/crd' | |
if git status --porcelain $crd_path | grep '^ M'; then | |
echo "The CRD manifests do not reflect the current API. Please run make manifests." | |
exit 1 | |
fi | |
buildx: | |
name: Build containers | |
needs: | |
- go-linters | |
- shellcheck | |
- tests | |
- apidoc | |
- crd | |
- duplicate_runs | |
- change-triage | |
# Build containers: | |
# if there have been any code changes OR it is a scheduled execution | |
# AND | |
# none of the preceding jobs failed | |
if: | | |
(always() && !cancelled()) && | |
( | |
needs.duplicate_runs.outputs.should_skip != 'true' && | |
( | |
needs.change-triage.outputs.operator-changed == 'true' || | |
needs.change-triage.outputs.test-changed == 'true' || | |
needs.change-triage.outputs.shell-script-changed == 'true' || | |
needs.change-triage.outputs.go-code-changed == 'true' | |
) | |
) && | |
(needs.go-linters.result == 'success' || needs.go-linters.result == 'skipped') && | |
(needs.shellcheck.result == 'success' || needs.shellcheck.result == 'skipped') && | |
(needs.tests.result == 'success' || needs.tests.result == 'skipped') && | |
(needs.apidoc.result == 'success' || needs.apidoc.result == 'skipped') && | |
(needs.crd.result == 'success' || needs.crd.result == 'skipped') | |
runs-on: ubuntu-24.04 | |
permissions: | |
actions: read | |
contents: read | |
packages: write | |
security-events: write | |
outputs: | |
commit_version: ${{ env.VERSION }} | |
commit: ${{ env.COMMIT_SHA }} | |
controller_img: ${{ env.CONTROLLER_IMG }} | |
controller_img_ubi8: ${{ env.CONTROLLER_IMG_UBI8 }} | |
bundle_img: ${{ env.BUNDLE_IMG }} | |
catalog_img: ${{ env.CATALOG_IMG }} | |
push: ${{ env.PUSH }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
# To identify the commit we need the history and all the tags. | |
fetch-depth: 0 | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Build meta | |
id: build-meta | |
run: | | |
commit_sha=${{ github.event.pull_request.head.sha || github.sha }} | |
commit_date=$(git log -1 --pretty=format:'%ad' --date short "${commit_sha}" || : ) | |
# use git describe to get the nearest tag and use that to build the version (e.g. 1.4.0-dev24 or 1.4.0) | |
commit_version=$(git describe --tags --match 'v*' "${commit_sha}"| sed -e 's/^v//; s/-g[0-9a-f]\+$//; s/-\([0-9]\+\)$/-dev\1/') | |
# shortened commit sha | |
commit_short=$(git rev-parse --short "${commit_sha}") | |
echo "DATE=${commit_date}" >> $GITHUB_ENV | |
echo "VERSION=${commit_version}" >> $GITHUB_ENV | |
echo "COMMIT=${commit_short}" >> $GITHUB_ENV | |
echo "COMMIT_SHA=${commit_sha}" >> $GITHUB_ENV | |
# By default the container image is being pushed to the registry | |
echo "PUSH=true" >> $GITHUB_ENV | |
# GITHUB_TOKEN has restricted permissions if the pull_request has been opened | |
# from a forked repository, so we avoid pushing to the container registry if | |
# that's the case. | |
- name: Evaluate container image push | |
if: github.event_name == 'pull_request' | |
env: | |
BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }} | |
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} | |
run: | | |
if [[ "${{ env.HEAD_REPO }}" != "${{ env.BASE_REPO }}" ]] | |
then | |
echo "PUSH=false" >> $GITHUB_ENV | |
fi | |
- name: Set GoReleaser environment | |
run: | | |
echo GOPATH=$(go env GOPATH) >> $GITHUB_ENV | |
echo PWD=$(pwd) >> $GITHUB_ENV | |
- name: Run GoReleaser to build kubectl plugin | |
uses: goreleaser/goreleaser-action@v6 | |
if: | | |
github.event_name == 'schedule' || | |
( | |
github.event_name == 'workflow_dispatch' && | |
startsWith(github.head_ref, 'release-') || | |
startsWith(github.ref_name, 'release-') | |
) | |
with: | |
distribution: goreleaser | |
version: v2 | |
args: ${{ env.BUILD_PLUGIN_RELEASE_ARGS }} | |
env: | |
DATE: ${{ env.DATE }} | |
COMMIT: ${{ env.COMMIT }} | |
VERSION: ${{ env.VERSION }} | |
# Send Slack notification if the kubectl plugin build fails. | |
# To avoid message overflow, we only report runs scheduled on main or release branches | |
- name: Slack Notification | |
uses: rtCamp/action-slack-notify@v2 | |
if: | | |
failure() && | |
github.repository_owner == env.REPOSITORY_OWNER && | |
( | |
github.event_name == 'schedule' || | |
( | |
github.event_name == 'workflow_dispatch' && | |
startsWith(github.head_ref, 'release-') || | |
startsWith(github.ref_name, 'release-') | |
) | |
) | |
env: | |
SLACK_COLOR: ${{ job.status }} | |
SLACK_ICON: https://avatars.githubusercontent.com/u/85171364?size=48 | |
SLACK_USERNAME: ${{ env.SLACK_USERNAME }} | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_MESSAGE: Building kubernetes plugin failed! | |
- name: Run GoReleaser | |
uses: goreleaser/goreleaser-action@v6 | |
with: | |
distribution: goreleaser | |
version: v2 | |
args: ${{ env.BUILD_MANAGER_RELEASE_ARGS }} | |
env: | |
DATE: ${{ env.DATE }} | |
COMMIT: ${{ env.COMMIT }} | |
VERSION: ${{ env.VERSION }} | |
- name: Docker meta | |
id: docker-meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.OPERATOR_IMAGE_NAME }} | |
tags: | | |
type=ref,event=branch | |
type=ref,event=pr | |
- name: Docker meta UBI8 | |
id: docker-meta-ubi8 | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.OPERATOR_IMAGE_NAME }} | |
flavor: | | |
suffix=-ubi8 | |
tags: | | |
type=ref,event=branch | |
type=ref,event=pr | |
- name: Docker meta UBI9 | |
id: docker-meta-ubi9 | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.OPERATOR_IMAGE_NAME }} | |
flavor: | | |
suffix=-ubi9 | |
tags: | | |
type=ref,event=branch | |
type=ref,event=pr | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login into docker registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ env.REGISTRY_USER }} | |
password: ${{ env.REGISTRY_PASSWORD }} | |
- name: Build for scan distroless image | |
uses: docker/build-push-action@v6 | |
with: | |
platforms: "linux/amd64" | |
context: . | |
file: Dockerfile | |
push: false | |
load: true | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta.outputs.tags }} | |
- name: Dockle scan distroless image | |
uses: erzz/dockle-action@v1 | |
with: | |
image: ${{ steps.docker-meta.outputs.tags }} | |
exit-code: '1' | |
failure-threshold: WARN | |
accept-keywords: key | |
- name: Build for scan UBI8 image | |
uses: docker/build-push-action@v6 | |
with: | |
platforms: "linux/amd64" | |
context: . | |
file: Dockerfile-ubi8 | |
push: false | |
load: true | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta-ubi8.outputs.tags }} | |
- name: Dockle scan UBI8 image | |
uses: erzz/dockle-action@v1 | |
env: | |
DOCKLE_IGNORES: CIS-DI-0009 | |
with: | |
image: ${{ steps.docker-meta-ubi8.outputs.tags }} | |
exit-code: '1' | |
failure-threshold: WARN | |
accept-keywords: key | |
- name: Build for scan UBI9 image | |
uses: docker/build-push-action@v6 | |
with: | |
platforms: "linux/amd64" | |
context: . | |
file: Dockerfile-ubi9 | |
push: false | |
load: true | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta-ubi9.outputs.tags }} | |
- name: Dockle scan UBI9 image | |
uses: erzz/dockle-action@v1 | |
env: | |
DOCKLE_IGNORES: CIS-DI-0009 | |
with: | |
image: ${{ steps.docker-meta-ubi9.outputs.tags }} | |
exit-code: '1' | |
failure-threshold: WARN | |
accept-keywords: key | |
- name: Run Snyk to check Docker image for vulnerabilities | |
uses: snyk/actions/docker@master | |
if: | | |
!github.event.repository.fork && | |
!github.event.pull_request.head.repo.fork | |
continue-on-error: true | |
env: | |
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
with: | |
image: ${{ steps.docker-meta.outputs.tags }} | |
args: --severity-threshold=high --file=Dockerfile | |
- name: Upload result to GitHub Code Scanning | |
uses: github/codeql-action/upload-sarif@v3 | |
if: | | |
!github.event.repository.fork && | |
!github.event.pull_request.head.repo.fork | |
continue-on-error: true | |
with: | |
sarif_file: snyk.sarif | |
- name: Build and push | |
uses: docker/build-push-action@v6 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
context: . | |
file: Dockerfile | |
push: ${{ env.PUSH }} | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta.outputs.tags }} | |
provenance: ${{ env.BUILD_PUSH_PROVENANCE }} | |
cache-from: ${{ env.BUILD_PUSH_CACHE_FROM }} | |
cache-to: ${{ env.BUILD_PUSH_CACHE_TO }} | |
- name: Build and push UBI8 | |
uses: docker/build-push-action@v6 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
context: . | |
file: Dockerfile-ubi8 | |
push: ${{ env.PUSH }} | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta-ubi8.outputs.tags }} | |
- name: Build and push UBI9 | |
uses: docker/build-push-action@v6 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
context: . | |
file: Dockerfile-ubi9 | |
push: ${{ env.PUSH }} | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta-ubi9.outputs.tags }} | |
- name: Output images | |
env: | |
TAGS: ${{ steps.docker-meta.outputs.tags }} | |
TAGS_UBI8: ${{ steps.docker-meta-ubi8.outputs.tags }} | |
run: | | |
LOWERCASE_OPERATOR_IMAGE_NAME=${OPERATOR_IMAGE_NAME,,} | |
TAG=${TAGS#*:} | |
TAG_UBI=${TAGS_UBI8#*:} | |
echo "CONTROLLER_IMG=${LOWERCASE_OPERATOR_IMAGE_NAME}:${TAG}" >> $GITHUB_ENV | |
echo "CONTROLLER_IMG_UBI8=${LOWERCASE_OPERATOR_IMAGE_NAME}:${TAG_UBI}" >> $GITHUB_ENV | |
echo "BUNDLE_IMG=${LOWERCASE_OPERATOR_IMAGE_NAME}:bundle-${TAG}" >> $GITHUB_ENV | |
echo "CATALOG_IMG=${LOWERCASE_OPERATOR_IMAGE_NAME}:catalog-${TAG}" >> $GITHUB_ENV | |
olm-bundle: | |
name: Create OLM bundle and catalog | |
runs-on: ubuntu-24.04 | |
permissions: | |
contents: read | |
packages: write | |
needs: | |
- buildx | |
if: | | |
(always() && !cancelled()) && | |
needs.buildx.result == 'success' && | |
needs.buildx.outputs.push == 'true' | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: ${{ needs.buildx.outputs.commit }} | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login into docker registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ env.REGISTRY_USER }} | |
password: ${{ env.REGISTRY_PASSWORD }} | |
- name: Create bundle | |
env: | |
CONTROLLER_IMG: ${{ needs.buildx.outputs.controller_img_ubi8 }} | |
BUNDLE_IMG: ${{ needs.buildx.outputs.bundle_img }} | |
CATALOG_IMG: ${{ needs.buildx.outputs.catalog_img }} | |
run: | | |
make olm-catalog | |
- name: Archive the bundle manifests | |
uses: actions/upload-artifact@v4 | |
with: | |
name: bundle | |
path: | | |
bundle.Dockerfile | |
bundle/ | |
cloudnative-pg-catalog.yaml | |
retention-days: 7 | |
preflight: | |
name: Run openshift-preflight test | |
runs-on: ubuntu-24.04 | |
needs: | |
- buildx | |
- olm-bundle | |
if: | | |
(always() && !cancelled()) && | |
needs.olm-bundle.result == 'success' | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Setup tools | |
run: | | |
make operator-sdk preflight | |
- name: Loging to container registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ env.REGISTRY_USER }} | |
password: ${{ env.REGISTRY_PASSWORD }} | |
- name: Run preflight container test | |
env: | |
CONTROLLER_IMG: ${{ needs.buildx.outputs.controller_img_ubi8 }} | |
PFLT_ARTIFACTS: "preflight_results" | |
run: | | |
bin/preflight check container ${CONTROLLER_IMG} \ | |
--docker-config $HOME/.docker/config.json | |
- name: Archive the preflight results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: preflight_results | |
path: | | |
preflight_results | |
retention-days: 7 | |
- name: Check preflight container results | |
run: | | |
for dir in `ls preflight_results`; do | |
PASS=`jq -r .passed preflight_results/$dir/results.json` | |
if [[ "$PASS" == "false" ]] | |
then | |
exit 1 | |
fi | |
done | |
olm-scorecard: | |
name: Run OLM scorecard test | |
runs-on: ubuntu-24.04 | |
needs: | |
- buildx | |
- olm-bundle | |
if: | | |
(always() && !cancelled()) && | |
needs.olm-bundle.result == 'success' && | |
github.repository_owner == 'cloudnative-pg' | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Setting up KinD cluster | |
uses: helm/[email protected] | |
with: | |
wait: "600s" | |
version: ${{ env.KIND_VERSION }} | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login into docker registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ env.REGISTRY_USER }} | |
password: ${{ env.REGISTRY_PASSWORD }} | |
- name: Install Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
check-latest: true | |
- name: Running Scorecard tests | |
env: | |
BUNDLE_IMG: ${{ needs.buildx.outputs.bundle_img }} | |
run: | | |
make olm-scorecard | |
olm-tests: | |
strategy: | |
fail-fast: false | |
matrix: | |
test: [ kiwi, lemon, orange ] | |
name: Run OLM ${{ matrix.test }} test | |
runs-on: ubuntu-24.04 | |
needs: | |
- buildx | |
- olm-bundle | |
if: | | |
(always() && !cancelled()) && | |
needs.olm-bundle.result == 'success' && | |
github.repository_owner == 'cloudnative-pg' | |
env: | |
VERSION: ${{ needs.buildx.outputs.commit_version }} | |
OPP_DEBUG: 1 | |
OPP_PRODUCTION_TYPE: "k8s" | |
OPP_CONTAINER_OPT: "-t" | |
OPP_RELEASE_INDEX_NAME: "catalog_tmp" | |
steps: | |
- name: Checkout community-operators | |
uses: actions/checkout@v4 | |
with: | |
repository: k8s-operatorhub/community-operators | |
persist-credentials: false | |
- name: Login into docker registry | |
uses: redhat-actions/podman-login@v1 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ env.REGISTRY_USER }} | |
password: ${{ env.REGISTRY_PASSWORD }} | |
- name: Download the bundle | |
uses: actions/download-artifact@v4 | |
with: | |
name: bundle | |
- name: Copy bundle in the community-operators | |
run: | | |
mkdir -p "operators/cloudnative-pg/${{ env.VERSION }}" | |
cp -R bundle/* "operators/cloudnative-pg/${{ env.VERSION }}" | |
rm -fr bundle.Dockerfile *.zip bundle/ | |
- name: Test bundle | |
run: | | |
bash <(curl -sL ${{ env.OPP_SCRIPT_URL }}) ${{ matrix.test }} operators/cloudnative-pg/${{ env.VERSION }}/ |