continuous-delivery #129
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 E2E Test Suite for a series of combinations that | |
# represent different execution environments | |
name: continuous-delivery | |
on: | |
issue_comment: | |
type: [created] | |
# Manually or triggered by another workflow | |
workflow_dispatch: | |
inputs: | |
depth: | |
description: 'Depth (push, pull_request, main, schedule)' | |
required: true | |
default: 'main' | |
test_level: | |
description: 'Test level (0-4)' | |
required: false | |
default: '1' | |
feature_type: | |
description: 'Feature Type (disruptive, performance, upgrade, smoke, basic, service-connectivity, self-healing, | |
backup-restore, operator, observability, replication, plugin, postgres-configuration, pod-scheduling, | |
cluster-metadata, recovery, importing-databases, storage, security, maintenance)' | |
required: false | |
log_level: | |
description: 'Log level for operator (error, warning, info(default), debug, trace)' | |
required: false | |
default: 'info' | |
build_plugin: | |
type: boolean | |
required: false | |
default: false | |
description: Include kubectl-cnpg plugin building | |
schedule: | |
- cron: '0 1 * * *' | |
# set up environment variables to be used across all the jobs | |
env: | |
GOLANG_VERSION: "1.20.x" | |
KUBEBUILDER_VERSION: "2.3.1" | |
KIND_VERSION: "v0.17.0" | |
CNPG_IMAGE_NAME: "ghcr.io/${{ github.repository }}-testing" | |
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-20.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.18 | |
- release-1.19 | |
steps: | |
- name: Invoke workflow with inputs | |
uses: benc-uk/workflow-dispatch@v1 | |
with: | |
workflow: continuous-delivery | |
ref: ${{ matrix.branch }} | |
inputs: '{ "depth": "push", "test_level": "4", "build_plugin": "true", "log_level": "debug" }' | |
check_commenter: | |
if: | | |
github.event_name == 'issue_comment' && | |
github.event.issue.pull_request && | |
startsWith(github.event.comment.body, '/test') | |
name: Retrieve command | |
runs-on: ubuntu-20.04 | |
outputs: | |
github_ref: ${{ steps.refs.outputs.head_sha }} | |
depth: ${{ env.DEPTH }} | |
test_level: ${{ env.TEST_LEVEL }} | |
feature_type: ${{ env.FEATURE_TYPE }} | |
log_level: ${{ env.LOG_LEVEL }} | |
build_plugin: ${{ env.BUILD_PLUGIN }} | |
steps: | |
- name: Check for Command | |
id: command | |
uses: xt0rted/slash-command-action@v2 | |
continue-on-error: false | |
with: | |
command: test | |
reaction: "true" | |
reaction-type: "eyes" | |
allow-edits: "false" | |
permission-level: write | |
- name: Process arguments | |
id: args | |
run: | | |
ARGS="${{ steps.command.outputs.command-arguments }}" | |
# Set the defaults | |
DEPTH="main" | |
TEST_LEVEL="4" | |
FEATURE_TYPE="" | |
BUILD_PLUGIN="false" | |
LOG_LEVEL="debug" | |
for ARG in $ARGS; do | |
IFS='=' read name value <<< $ARG | |
case "${name}" in | |
"depth"|"d") | |
DEPTH="${value}" | |
;; | |
"test_level"|"level"|"tl") | |
TEST_LEVEL="${value}" | |
;; | |
"feature_type"|"type"|"ft") | |
FEATURE_TYPE="${value}" | |
;; | |
"build_plugin"|"plugin"|"bp") | |
BUILD_PLUGIN="${value}" | |
;; | |
"log_level"|"ll") | |
LOG_LEVEL="${value}" | |
;; | |
*) | |
;; | |
esac | |
done | |
echo "DEPTH=${DEPTH}" >> $GITHUB_ENV | |
echo "TEST_LEVEL=${TEST_LEVEL}" >> $GITHUB_ENV | |
echo "FEATURE_TYPE=${FEATURE_TYPE}" >> $GITHUB_ENV | |
echo "BUILD_PLUGIN=${BUILD_PLUGIN}" >> $GITHUB_ENV | |
echo "LOG_LEVEL=${LOG_LEVEL}" >> $GITHUB_ENV | |
- name: Resolve Git reference | |
uses: xt0rted/pull-request-comment-branch@v1 | |
id: refs | |
- name: Create comment | |
uses: peter-evans/create-or-update-comment@v2 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
repository: ${{ github.repository }} | |
issue-number: ${{ github.event.issue.number }} | |
body: | | |
@${{ github.actor }}, here's the link to the E2E on CNPG workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
test_arguments: | |
name: Parse arguments | |
if: | | |
github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' | |
runs-on: ubuntu-20.04 | |
outputs: | |
github_ref: ${{ github.ref }} | |
depth: ${{ env.DEPTH }} | |
test_level: ${{ env.TEST_LEVEL }} | |
feature_type: ${{ env.FEATURE_TYPE }} | |
build_plugin: ${{ env.BUILD_PLUGIN }} | |
log_level: ${{ env.LOG_LEVEL }} | |
steps: | |
- name: Parse input to env | |
run: | | |
# Set the defaults for workflow dispatch | |
if [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then | |
DEPTH=${{ github.event.inputs.depth }} | |
TEST_LEVEL=${{ github.event.inputs.test_level }} | |
FEATURE_TYPE="${{ github.event.inputs.feature_type }}" | |
BUILD_PLUGIN="${{ github.event.inputs.build_plugin }}" | |
LOG_LEVEL="${{ github.event.inputs.log_level }}" | |
fi | |
# Set the defaults for schedule dispatch | |
if [[ ${{ github.event_name }} == 'schedule' ]]; then | |
DEPTH="schedule" | |
TEST_LEVEL="4" | |
FEATURE_TYPE="" | |
BUILD_PLUGIN="true" | |
LOG_LEVEL="debug" | |
fi | |
echo "DEPTH=${DEPTH}" >> $GITHUB_ENV | |
echo "TEST_LEVEL=${TEST_LEVEL}" >> $GITHUB_ENV | |
echo "FEATURE_TYPE=${FEATURE_TYPE}" >> $GITHUB_ENV | |
echo "BUILD_PLUGIN=${BUILD_PLUGIN}" >> $GITHUB_ENV | |
echo "LOG_LEVEL=${LOG_LEVEL}" >> $GITHUB_ENV | |
evaluate_options: | |
name: Evaluate workflow options | |
needs: | |
- check_commenter | |
- test_arguments | |
runs-on: ubuntu-20.04 | |
if: | | |
( | |
needs.check_commenter.result == 'success' || | |
needs.test_arguments.result == 'success' | |
) && | |
!cancelled() | |
outputs: | |
git_ref: ${{ env.GITHUB_REF }} | |
depth: ${{ env.DEPTH }} | |
test_level: ${{ env.TEST_LEVEL }} | |
feature_type: ${{ env.FEATURE_TYPE }} | |
build_plugin: ${{ env.BUILD_PLUGIN }} | |
log_level: ${{ env.LOG_LEVEL }} | |
steps: | |
- name: From command | |
run: | | |
if [[ ${{ github.event_name }} == 'workflow_dispatch' ]] || [[ ${{ github.event_name }} == 'schedule' ]]; then | |
echo 'GITHUB_REF=${{ needs.test_arguments.outputs.github_ref }}' >> $GITHUB_ENV | |
echo 'DEPTH=${{ needs.test_arguments.outputs.depth }}' >> $GITHUB_ENV | |
echo 'TEST_LEVEL=${{ needs.test_arguments.outputs.test_level }}' >> $GITHUB_ENV | |
echo 'FEATURE_TYPE=${{ needs.test_arguments.outputs.feature_type }}' >> $GITHUB_ENV | |
echo 'BUILD_PLUGIN=${{ needs.test_arguments.outputs.build_plugin }}' >> $GITHUB_ENV | |
echo 'LOG_LEVEL=${{ needs.test_arguments.outputs.log_level }}' >> $GITHUB_ENV | |
fi | |
if [[ ${{ github.event_name }} == 'issue_comment' ]]; then | |
echo 'GITHUB_REF=${{ needs.check_commenter.outputs.github_ref }}' >> $GITHUB_ENV | |
echo 'DEPTH=${{ needs.check_commenter.outputs.depth }}' >> $GITHUB_ENV | |
echo 'TEST_LEVEL=${{ needs.check_commenter.outputs.test_level }}' >> $GITHUB_ENV | |
echo 'FEATURE_TYPE=${{ needs.check_commenter.outputs.feature_type }}' >> $GITHUB_ENV | |
echo 'BUILD_PLUGIN=${{ needs.check_commenter.outputs.build_plugin }}' >> $GITHUB_ENV | |
echo 'LOG_LEVEL=${{ needs.check_commenter.outputs.log_level }}' >> $GITHUB_ENV | |
fi | |
buildx: | |
name: Build containers | |
needs: | |
- check_commenter | |
- test_arguments | |
- evaluate_options | |
if: | | |
always() && !cancelled() && | |
needs.evaluate_options.result == 'success' | |
runs-on: ubuntu-20.04 | |
permissions: | |
contents: read | |
packages: write | |
outputs: | |
image: ${{ steps.image-meta.outputs.image }} | |
# 'branch_name' is used in 'GetMostRecentReleaseTag' in the Go code | |
branch_name: ${{ steps.build-meta.outputs.branch_name }} | |
upload_artifacts: ${{ steps.build-meta.outputs.upload_artifacts }} | |
commit_msg: ${{ steps.build-meta.outputs.commit_msg }} | |
commit_sha: ${{ steps.build-meta.outputs.commit_sha }} | |
author_name: ${{ steps.build-meta.outputs.author_name }} | |
author_email: ${{ steps.build-meta.outputs.author_email }} | |
steps: | |
- | |
name: Checkout | |
uses: actions/checkout@v3 | |
with: | |
ref: ${{ needs.evaluate_options.outputs.git_ref }} | |
# To identify the commit we need the history and all the tags. | |
fetch-depth: 0 | |
- | |
name: Install Go | |
uses: actions/setup-go@v4 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
- | |
name: Build meta | |
id: build-meta | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
images='${{ env.CNPG_IMAGE_NAME }}' | |
tags='' | |
labels='' | |
commit_sha=${{ needs.evaluate_options.outputs.git_ref }} | |
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}") | |
# multiline strings are weird | |
commit_message=$(git show -s --format=%B "${commit_sha}") | |
commit_message=${commit_message//$'%'/'%25'} | |
commit_message=${commit_message//$'\n'/'%0A'} | |
commit_message=${commit_message//$'\r'/'%0D'} | |
# get git user and email | |
author_name=$(git show -s --format='%an' "${commit_sha}") | |
author_email=$(git show -s --format='%ae' "${commit_sha}") | |
# extract branch name | |
if [[ ${{ github.event_name }} == 'workflow_dispatch' ]] || [[ ${{ github.event_name }} == 'schedule' ]] | |
then | |
branch_name=${GITHUB_REF#refs/heads/} | |
fi | |
if [[ ${{ github.event_name }} == 'issue_comment' ]] | |
then | |
branch_name=$(gh pr view "${{ github.event.issue.number }}" --json headRefName -q '.headRefName' 2>/dev/null) | |
fi | |
upload_artifacts=false | |
if [[ ${branch_name} == main || ${branch_name} =~ ^release- ]]; then | |
upload_artifacts=true | |
fi | |
echo "IMAGES=${images}" >> $GITHUB_ENV | |
echo "TAGS=${tags}" >> $GITHUB_ENV | |
echo "LABELS=${labels}" >> $GITHUB_ENV | |
echo "DATE=${commit_date}" >> $GITHUB_ENV | |
echo "VERSION=${commit_version}" >> $GITHUB_ENV | |
echo "COMMIT=${commit_short}" >> $GITHUB_ENV | |
echo "commit_sha=${commit_sha}" >> $GITHUB_OUTPUT | |
echo "commit_msg=${commit_message}" >> $GITHUB_OUTPUT | |
echo "author_name=${author_name}" >> $GITHUB_OUTPUT | |
echo "author_email=${author_email}" >> $GITHUB_OUTPUT | |
echo "branch_name=${branch_name}" >> $GITHUB_OUTPUT | |
echo "upload_artifacts=${upload_artifacts}" >> $GITHUB_OUTPUT | |
- | |
name: Set GoReleaser environment | |
run: | | |
echo GOPATH=$(go env GOPATH) >> $GITHUB_ENV | |
echo PWD=$(pwd) >> $GITHUB_ENV | |
- | |
name: Run GoReleaser to build kubectl-cnpg plugin | |
uses: goreleaser/goreleaser-action@v4 | |
if: | | |
github.event_name == 'schedule' || needs.evaluate_options.outputs.build_plugin == 'true' | |
with: | |
distribution: goreleaser | |
version: latest | |
args: build --skip-validate --rm-dist --id kubectl-cnpg | |
env: | |
DATE: ${{ env.DATE }} | |
COMMIT: ${{ env.COMMIT }} | |
VERSION: ${{ env.VERSION }} | |
# Send Slack notification once build including plugin kubectl-cnpg fails, we only report the scheduled run to avoid message overflow | |
- | |
name: Slack Notification | |
uses: rtCamp/action-slack-notify@v2 | |
if: | | |
failure() && github.event_name == 'schedule' && | |
github.organization == 'cloudnative-pg' | |
env: | |
SLACK_COLOR: ${{ job.status }} | |
SLACK_ICON: https://avatars.githubusercontent.com/u/85171364?size=48 | |
SLACK_USERNAME: cnpg-bot | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_MESSAGE: Building plugin `kubectl-cnpg` failed! | |
- | |
name: Run GoReleaser | |
uses: goreleaser/goreleaser-action@v4 | |
with: | |
distribution: goreleaser | |
version: latest | |
args: build --skip-validate --rm-dist --id manager | |
env: | |
DATE: ${{ env.DATE }} | |
COMMIT: ${{ env.COMMIT }} | |
VERSION: ${{ env.VERSION }} | |
- | |
name: Docker meta | |
id: docker-meta | |
uses: docker/metadata-action@v4 | |
with: | |
images: ${{ env.IMAGES }} | |
tags: | | |
type=ref,event=branch | |
type=ref,event=pr | |
- | |
name: Detect platforms | |
run: | | |
# 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" | |
echo "PLATFORMS=${platforms}" >> $GITHUB_ENV | |
- | |
name: Set up QEMU | |
uses: docker/setup-qemu-action@v2 | |
with: | |
image: tonistiigi/binfmt:qemu-v6.2.0 | |
platforms: ${{ env.PLATFORMS }} | |
- | |
name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
- | |
name: Login to ghcr.io | |
uses: docker/login-action@v2 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- | |
name: Build and push | |
uses: docker/build-push-action@v4 | |
with: | |
platforms: ${{ env.PLATFORMS }} | |
context: . | |
push: true | |
build-args: | | |
VERSION=${{ env.VERSION }} | |
tags: ${{ steps.docker-meta.outputs.tags }} | |
labels: ${{ env.LABELS }} | |
secrets: GIT_AUTH_TOKEN=${{ secrets.GITHUB_TOKEN }} | |
- | |
name: Image Meta | |
id: image-meta | |
env: | |
TAGS: ${{ steps.docker-meta.outputs.tags }} | |
run: | | |
# If there is more than one tag, take the first one | |
# TAGS could be separated by newlines or commas | |
image=$(sed -n '1{s/,.*//; p}' <<< "$TAGS") | |
echo "image=${image}" >> $GITHUB_OUTPUT | |
- | |
name: Generate manifest for operator deployment | |
id: generate-manifest | |
env: | |
CONTROLLER_IMG: ${{ steps.image-meta.outputs.image }} | |
run: | | |
make generate-manifest | |
- | |
name: Upload the operator manifest as artifact in workflow | |
uses: actions/upload-artifact@v3 | |
with: | |
name: operator-manifest.yaml | |
path: dist/operator-manifest.yaml | |
retention-days: 7 | |
publish-artifacts: | |
name: Publish artifacts | |
needs: | |
- buildx | |
if: | | |
(always() && !cancelled()) && | |
needs.buildx.result == 'success' && | |
needs.buildx.outputs.upload_artifacts == 'true' && | |
github.repository_owner == 'cloudnative-pg' | |
runs-on: ubuntu-20.04 | |
steps: | |
- | |
name: Checkout artifact | |
uses: actions/checkout@v3 | |
with: | |
repository: cloudnative-pg/artifacts | |
token: ${{ secrets.REPO_GHA_PAT }} | |
ref: main | |
fetch-depth: 0 | |
- | |
name: Configure git user | |
run: | | |
git config user.email "${{ needs.buildx.outputs.author_email }}" | |
git config user.name "${{ needs.buildx.outputs.author_name }}" | |
- | |
name: Switch to or create the right branch | |
env: | |
BRANCH: ${{ needs.buildx.outputs.branch_name }} | |
run: | | |
git checkout "${BRANCH}" 2>/dev/null || git checkout -b "${BRANCH}" | |
# Remove the previous operator manifest if present because the next | |
# step doesn't overwrite existing files | |
rm -fr manifests/operator-manifest.yaml | |
- | |
name: Prepare the operator manifest | |
uses: actions/download-artifact@v3 | |
with: | |
name: operator-manifest.yaml | |
path: manifests | |
- | |
name: Prepare the commit | |
env: | |
COMMIT_MESSAGE: | | |
${{ needs.buildx.outputs.commit_msg }} | |
https://github.com/cloudnative-pg/cloudnative-pg/commit/${{ needs.buildx.outputs.commit_sha }} | |
run: | | |
# Skip creating the commit if there are no changes | |
[ -n "$(git status -s)" ] || exit 0 | |
git add . | |
git commit -m "${COMMIT_MESSAGE}" | |
- | |
name: Push changes | |
uses: ad-m/[email protected] | |
with: | |
github_token: ${{ secrets.REPO_GHA_PAT }} | |
repository: cloudnative-pg/artifacts | |
branch: ${{ needs.buildx.outputs.branch_name }} | |
generate-jobs: | |
name: Generate jobs for E2E tests | |
needs: | |
- buildx | |
- evaluate_options | |
# We try to avoid running the E2E Test Suite in general, to reduce load on | |
# GitHub resources. | |
# Currently it's executed in the following cases: | |
# - When dispatched via chatops commands | |
# - On a push in main and release branches | |
# - On scheduled executions | |
if: | | |
(always() && !cancelled()) && | |
needs.buildx.result == 'success' | |
runs-on: ubuntu-20.04 | |
outputs: | |
image: ${{ needs.buildx.outputs.image }} | |
localMatrix: ${{ steps.generate-jobs.outputs.localMatrix }} | |
localEnabled: ${{ steps.generate-jobs.outputs.localEnabled }} | |
steps: | |
- | |
name: Checkout code | |
uses: actions/checkout@v3 | |
with: | |
ref: ${{ needs.evaluate_options.outputs.git_ref }} | |
- | |
id: generate-jobs | |
name: Generate Jobs | |
shell: bash | |
run: | | |
python .github/e2e-matrix-generator.py \ | |
-m '${{ needs.evaluate_options.outputs.depth }}' | |
e2e-local: | |
name: Run E2E on local executors | |
if: | | |
(always() && !cancelled()) && | |
needs.generate-jobs.outputs.localEnabled == 'true' && | |
needs.generate-jobs.result == 'success' | |
needs: | |
- buildx | |
- generate-jobs | |
- evaluate_options | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.generate-jobs.outputs.localMatrix) }} | |
runs-on: ubuntu-20.04 | |
env: | |
# TEST_DEPTH determines the matrix of K8S_VERSION x POSTGRES_VERSION jobs where E2E tests will be executed | |
TEST_DEPTH: ${{ needs.evaluate_options.outputs.test_level }} | |
# FEATURE_TYPE, when defined, determines the subset of E2E tests that will be executed, divided by feature type | |
FEATURE_TYPE: ${{ needs.evaluate_options.outputs.feature_type }} | |
K8S_VERSION: "${{ matrix.k8s_version }}" | |
POSTGRES_VERSION: ${{ matrix.postgres_version }} | |
MATRIX: ${{ matrix.id }} | |
POSTGRES_IMG: "${{ matrix.postgres_img }}" | |
# The version of operator to upgrade FROM, in the rolling upgrade E2E test | |
E2E_PRE_ROLLING_UPDATE_IMG: "${{ matrix.postgres_pre_img }}" | |
BRANCH_NAME: ${{ needs.buildx.outputs.branch_name }} | |
DOCKER_SERVER: ghcr.io | |
DOCKER_USERNAME: ${{ github.actor }} | |
DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
DEBUG: "true" | |
BUILD_IMAGE: "false" | |
CONTROLLER_IMG: ${{ needs.generate-jobs.outputs.image }} | |
E2E_DEFAULT_STORAGE_CLASS: standard | |
LOG_DIR: ${{ github.workspace }}/kind-logs/ | |
DOCKER_REGISTRY_MIRROR: https://mirror.gcr.io | |
steps: | |
- | |
name: Cleanup Disk | |
uses: jlumbroso/free-disk-space@main | |
with: | |
android: true | |
dotnet: true | |
haskell: true | |
tool-cache: true | |
large-packages: false | |
swap-storage: false | |
- | |
name: Cleanup docker cache | |
run: | | |
echo "-------------Disk info before cleanup----------------" | |
df -h | |
echo "-----------------------------------------------------" | |
docker system prune -a -f | |
echo "-------------Disk info after cleanup----------------" | |
df -h | |
echo "-----------------------------------------------------" | |
- | |
name: Checkout code | |
uses: actions/checkout@v3 | |
with: | |
ref: ${{ needs.evaluate_options.outputs.git_ref }} | |
- | |
name: Install Go | |
uses: actions/setup-go@v4 | |
with: | |
go-version: ${{ env.GOLANG_VERSION }} | |
- | |
# 'Retry' preparing the E2E test ENV | |
name: Prepare the environment | |
uses: nick-fields/retry@v2 | |
with: | |
timeout_seconds: 120 | |
max_attempts: 3 | |
on_retry_command: | | |
# Clear-ups before retries | |
rm -rf /usr/local/bin/kind /usr/local/bin/kubectl | |
command: | | |
sudo apt-get update | |
sudo apt-get install -y gettext-base | |
sudo hack/setup-cluster.sh prepare /usr/local/bin | |
- | |
name: Prepare patch for customization | |
env: | |
## the following variable all need be set if we use env_override_customized.yaml.template | |
LEADER_ELECTION: "true" | |
LEADER_LEASE_DURATION: 15 | |
LEADER_RENEW_DEADLINE: 10 | |
LIVENESS_PROBE_THRESHOLD: 3 | |
LOG_LEVEL: ${{ needs.evaluate_options.outputs.log_level }} | |
run: | | |
LOG_LEVEL=${LOG_LEVEL:-info} | |
envsubst < hack/e2e/env_override_customized.yaml.template > config/manager/env_override.yaml | |
cat config/manager/env_override.yaml | |
- | |
name: Run Kind End-to-End tests | |
run: | |
make e2e-test-kind | |
- | |
# Summarize the failed E2E test cases if there are any | |
name: Report failed E2E tests | |
if: failure() | |
run: | | |
set +x | |
chmod +x .github/report-failed-test.sh | |
./.github/report-failed-test.sh | |
- | |
# Create an individual artifact for each E2E test, which will be used to | |
# generate E2E test summary in the follow-up job 'summarize-e2e-tests' | |
name: Create individual artifact for each E2E test | |
if: (always() && !cancelled()) | |
run: | | |
set +x | |
echo '{"runner": "local", "postgres": "${{env.POSTGRES_VERSION}}", "kubernetes": "${{env.K8S_VERSION}}", "runid": ${{ github.run_id }}, "id": "${{ env.MATRIX }}", "repo": "${{github.repository}}", "branch": "${{github.head_ref}}", "refname": "${{github.ref_name}}" }' | |
python .github/generate-test-artifacts.py \ | |
-o testartifacts-${{ env.MATRIX }} \ | |
-f tests/e2e/out/report.json \ | |
-m '{"runner": "local", "postgres": "${{env.POSTGRES_VERSION}}", "kubernetes": "${{env.K8S_VERSION}}", "runid": ${{ github.run_id }}, "id": "${{ env.MATRIX }}", "repo": "${{github.repository}}", "branch": "${{github.head_ref}}", "refname": "${{github.ref_name}}" }' | |
if [ -f tests/e2e/out/upgrade_report.json ]; then | |
python .github/generate-test-artifacts.py \ | |
-o testartifacts-${{ env.MATRIX }} \ | |
-f tests/e2e/out/upgrade_report.json \ | |
-m '{"runner": "local", "postgres": "${{env.POSTGRES_VERSION}}", "kubernetes": "${{env.K8S_VERSION}}", "runid": ${{ github.run_id }}, "id": "${{ env.MATRIX }}", "repo": "${{github.repository}}", "branch": "${{github.head_ref}}", "refname": "${{github.ref_name}}" }' | |
fi | |
- | |
name: Archive test artifacts | |
if: (always() && !cancelled()) | |
uses: actions/upload-artifact@v3 | |
with: | |
name: testartifacts-local | |
path: testartifacts-${{ env.MATRIX }}/ | |
retention-days: 7 | |
- | |
name: Cleanup test artifacts | |
if: always() | |
run: | |
rm -rf testartifacts-${{ env.MATRIX }}/ | |
- | |
name: Cleanup ginkgo JSON report | |
# Delete report.json after the analysis. File should always exist. | |
# Delete upgrade_report.json. It may not exist depending on test level. | |
if: always() | |
run: | | |
if [ -f tests/e2e/out/upgrade_report.json ]; then | |
rm tests/e2e/out/upgrade_report.json | |
fi | |
if [ -f tests/e2e/out/report.json ]; then | |
rm tests/e2e/out/report.json | |
fi | |
- | |
# Archive logs for failed test cases if there are any | |
name: Archive Kind logs | |
if: failure() | |
uses: actions/upload-artifact@v3 | |
with: | |
name: kind-logs-${{ matrix.id }} | |
path: kind-logs/ | |
retention-days: 7 | |
- | |
name: Archive e2e failure contexts | |
if: failure() | |
uses: actions/upload-artifact@v3 | |
with: | |
name: test-failure-contexts-${{ matrix.id }} | |
path: | | |
tests/*/out/ | |
retention-days: 7 | |
if-no-files-found: ignore | |
# Summarize E2E test results, display in the GitHub 'summary' view | |
summarize-e2e-tests: | |
name: E2E test suite | |
needs: | |
- e2e-local | |
if: | | |
always() && !cancelled() && | |
( | |
needs.e2e-local.result == 'success' || | |
needs.e2e-local.result == 'failure' | |
) | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: Create a directory for the artifacts | |
run: mkdir test-artifacts | |
- name: Download all artifacts to the directory | |
uses: actions/download-artifact@v3 | |
with: | |
path: test-artifacts | |
- name: Flatten all artifacts onto directory | |
# The download-artifact action, since we did not give it a name, | |
# downloads all artifacts and creates a new folder for each. | |
# In this step we bring all the JSONs to a single folder | |
run: | | |
mkdir test-artifacts/data | |
mv test-artifacts/*/*.json test-artifacts/data | |
- name: Display the structure of the artifact folder | |
run: ls -R test-artifacts/data | |
- name: Compute the E2E test summary | |
uses: cloudnative-pg/[email protected] | |
with: | |
artifact_directory: test-artifacts/data | |
output_file: test-summary.md | |
- name: Create GitHub Job Summary from the file | |
run: cat test-summary.md >> $GITHUB_STEP_SUMMARY | |
- name: Delete the downloaded files | |
run: rm -rf test-artifacts | |
# Adds the 'ok-to-merge' label to workflows that have run successfully and | |
# have adequate test and matrix coverage. | |
# This label is a prerequisite to be able to merge a PR. | |
# Also see to 'require-labels.yml' | |
ok-to-merge: | |
name: Label the PR as "ok to merge :ok_hand:" | |
needs: | |
- evaluate_options | |
- e2e-local | |
if: | | |
always() && | |
needs.e2e-local.result == 'success' && | |
github.event_name == 'issue_comment' && | |
needs.evaluate_options.outputs.test_level == '4' | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: Check preconditions | |
id: get_pr_number_and_labels | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
ok_label=$(gh pr view "${{ github.event.issue.number }}" --json labels -q ".labels.[].name" 2>/dev/null | grep "ok to merge :ok_hand:" || :) | |
echo "OK_LABEL=${ok_label}" >> $GITHUB_ENV | |
- name: Label the PR as "ok to merge :ok_hand:" | |
if: | | |
env.OK_LABEL == '' | |
uses: actions-ecosystem/[email protected] | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
number: ${{ github.event.issue.number }} | |
labels: "ok to merge :ok_hand:" | |
# Remove the "ok to merge :ok_hand:" label if the E2E tests or previous steps failed | |
unlabel-ok-to-merge: | |
name: Remove the "ok to merge :ok_hand:" label from the PR | |
needs: | |
- evaluate_options | |
- e2e-local | |
if: | | |
always() && | |
needs.e2e-local.result == 'failure' && | |
github.event_name == 'issue_comment' | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: Check preconditions | |
id: get_pr_number_and_labels | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
ok_label=$(gh pr view "${{ github.event.issue.number }}" --json labels -q ".labels.[].name" 2>/dev/null | grep "ok to merge :ok_hand:" || :) | |
echo "OK_LABEL=${ok_label}" >> $GITHUB_ENV | |
- name: Remove "ok to merge :ok_hand:" label from PR | |
if: | | |
env.OK_LABEL != '' | |
uses: actions-ecosystem/[email protected] | |
with: | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
number: ${{ github.event.issue.number }} | |
labels: "ok to merge :ok_hand:" |