CI on "docs/release-5.2.1" by @vepatel #20762
This file contains hidden or 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
name: CI | |
run-name: CI on "${{ github.head_ref && github.head_ref || github.ref }}" by @${{ github.actor }} | |
on: | |
pull_request: | |
branches: | |
- main | |
- release-* | |
merge_group: | |
workflow_dispatch: | |
inputs: | |
force: | |
type: boolean | |
description: "Force rebuild" | |
required: false | |
default: false | |
run_tests: | |
type: boolean | |
description: "Run unit & e2e tests" | |
required: false | |
default: true | |
defaults: | |
run: | |
shell: bash | |
concurrency: | |
group: ${{ github.ref_name }}-ci | |
cancel-in-progress: true | |
permissions: | |
contents: read | |
jobs: | |
checks: | |
name: Checks and variables | |
runs-on: ubuntu-24.04 | |
permissions: | |
contents: read | |
id-token: write | |
outputs: | |
docs_only: ${{ github.event.pull_request && steps.docs.outputs.docs_only == 'true' }} | |
k8s_latest: ${{ steps.vars.outputs.k8s_latest }} | |
go_path: ${{ steps.vars.outputs.go_path }} | |
go_code_md5: ${{ steps.vars.outputs.go_code_md5 }} | |
go_proxy: ${{ steps.vars.outputs.go_proxy }} | |
binary_cache_hit: ${{ steps.binary-cache.outputs.cache-hit }} | |
chart_version: ${{ steps.vars.outputs.chart_version }} | |
ic_version: ${{ steps.vars.outputs.ic_version }} | |
docker_md5: ${{ steps.vars.outputs.docker_md5 }} | |
build_tag: ${{ steps.vars.outputs.build_tag }} | |
stable_tag: ${{ steps.vars.outputs.stable_tag }} | |
forked_workflow: ${{ steps.vars.outputs.forked_workflow }} | |
stable_image_exists: ${{ steps.stable_exists.outputs.exists }} | |
additional_tag: ${{ steps.vars.outputs.additional_tag }} | |
image_matrix_oss: ${{ steps.vars.outputs.image_matrix_oss }} | |
image_matrix_plus: ${{ steps.vars.outputs.image_matrix_plus }} | |
image_matrix_nap: ${{ steps.vars.outputs.image_matrix_nap }} | |
docker_build: ${{ steps.docker_build.outputs.docker_build }} | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
with: | |
fetch-depth: 0 | |
- name: Filter only docs changes | |
id: docs | |
run: | | |
files=$(git diff --name-only HEAD^ | egrep -v "^examples/" | egrep -v "^README.md") | |
docs_files=$(git diff --name-only HEAD^) | |
if [ -z "$files" ]; then | |
echo "docs_only=true" >> $GITHUB_OUTPUT | |
else | |
echo "docs_only=false" >> $GITHUB_OUTPUT | |
fi | |
echo $files | |
echo $docs_files | |
cat $GITHUB_OUTPUT | |
shell: bash --noprofile --norc -o pipefail {0} | |
- name: Setup Golang Environment | |
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 | |
with: | |
go-version-file: go.mod | |
- name: Configure pipeline Variables | |
id: vars | |
run: | | |
kindest_latest=$(curl -s "https://hub.docker.com/v2/repositories/kindest/node/tags" \ | |
| jq -r '.results[].name' \ | |
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \ | |
| sort -rV \ | |
| grep -v v1.32.1 \ | |
| head -n 1 \ | |
| sed 's/^.\{1\}//' \ | |
| tr -d '\n') | |
echo "k8s_latest=$kindest_latest" >> $GITHUB_OUTPUT | |
echo "go_path=$(go env GOPATH)" >> $GITHUB_OUTPUT | |
source .github/data/version.txt | |
echo "ic_version=${IC_VERSION}" >> $GITHUB_OUTPUT | |
echo "chart_version=${HELM_CHART_VERSION}" >> $GITHUB_OUTPUT | |
forked_workflow=${{ (github.event.pull_request && github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) || github.repository != 'nginx/kubernetes-ingress' }} | |
echo "forked_workflow=${forked_workflow}" >> $GITHUB_OUTPUT | |
go_proxy="https://proxy.golang.org,direct" | |
if [ "$forked_workflow" = "false" ]; then | |
go_proxy="${{ secrets.ARTIFACTORY_DEV_ENDPOINT }}" | |
elif [ "${{ github.ref_name }}" = "main" ] || [[ "${{ github.ref_name }}" =~ "release-" ]]; then | |
go_proxy="${{ secrets.ARTIFACTORY_ENDPOINT }}" | |
fi | |
echo "go_proxy=${go_proxy}" >> $GITHUB_OUTPUT | |
./.github/scripts/variables.sh go_code_md5 >> $GITHUB_OUTPUT | |
./.github/scripts/variables.sh docker_md5 >> $GITHUB_OUTPUT | |
./.github/scripts/variables.sh build_tag >> $GITHUB_OUTPUT | |
./.github/scripts/variables.sh stable_tag >> $GITHUB_OUTPUT | |
REF=${{ github.ref_name }} ./.github/scripts/variables.sh additional_tag >> $GITHUB_OUTPUT | |
echo "image_matrix_oss=$(cat .github/data/matrix-images-oss.json | jq -c)" >> $GITHUB_OUTPUT | |
echo "image_matrix_plus=$(cat .github/data/matrix-images-plus.json | jq -c)" >> $GITHUB_OUTPUT | |
echo "image_matrix_nap=$(cat .github/data/matrix-images-nap.json | jq -c)" >> $GITHUB_OUTPUT | |
cat $GITHUB_OUTPUT | |
- name: Fetch Cached Binary Artifacts | |
id: binary-cache | |
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | |
with: | |
path: ${{ github.workspace }}/dist | |
key: nginx-ingress-${{ steps.vars.outputs.go_code_md5 }} | |
lookup-only: true | |
- name: Authenticate to Google Cloud | |
id: auth | |
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 | |
with: | |
token_format: access_token | |
workload_identity_provider: ${{ secrets.GCR_WORKLOAD_IDENTITY }} | |
service_account: ${{ secrets.GCR_SERVICE_ACCOUNT }} | |
if: ${{ steps.vars.outputs.forked_workflow == 'false' }} | |
- name: Login to GCR | |
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 | |
with: | |
registry: gcr.io | |
username: oauth2accesstoken | |
password: ${{ steps.auth.outputs.access_token }} | |
if: ${{ steps.vars.outputs.forked_workflow == 'false' }} | |
- name: Check if stable image exists | |
id: stable_exists | |
run: | | |
exists=false | |
if docker pull gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress:${{ steps.vars.outputs.stable_tag }}; then | |
exists=true | |
fi | |
echo "exists=${exists}" >> $GITHUB_OUTPUT | |
if: ${{ steps.vars.outputs.forked_workflow == 'false' }} | |
- name: Check if docker build is needed | |
id: docker_build | |
run: | | |
docker_build="false" | |
if [ "${{ inputs.force }}" = "true" ]; then | |
docker_build="true" | |
elif [ "${{ steps.vars.outputs.forked_workflow }}" = "true" ] && [ "${{ steps.docs.outputs.docs_only }}" = "false" ]; then | |
docker_build="true" | |
elif [ "${{ steps.vars.outputs.forked_workflow }}" = "false" ] && [ "${{ steps.docs.outputs.docs_only }}" = "false" ] && [ "${{ steps.stable_exists.outputs.exists }}" = "false" ]; then | |
docker_build="true" | |
fi | |
echo "docker_build=${docker_build}" >> $GITHUB_OUTPUT | |
cat $GITHUB_OUTPUT | |
- name: Output variables | |
run: | | |
echo docs_only: ${{ github.event.pull_request && steps.docs.outputs.docs_only == 'true' }} | |
echo k8s_latest: ${{ steps.vars.outputs.k8s_latest }} | |
echo go_path: ${{ steps.vars.outputs.go_path }} | |
echo go_code_md5: ${{ steps.vars.outputs.go_code_md5 }} | |
echo binary_cache_hit: ${{ steps.binary-cache.outputs.cache-hit }} | |
echo chart_version: ${{ steps.vars.outputs.chart_version }} | |
echo ic_version: ${{ steps.vars.outputs.ic_version }} | |
echo docker_md5: ${{ steps.vars.outputs.docker_md5 }} | |
echo build_tag: ${{ steps.vars.outputs.build_tag }} | |
echo stable_tag: ${{ steps.vars.outputs.stable_tag }} | |
echo forked_workflow: ${{ steps.vars.outputs.forked_workflow }} | |
echo stable_image_exists: ${{ steps.stable_exists.outputs.exists }} | |
echo additional_tag: ${{ steps.vars.outputs.additional_tag }} | |
echo 'image_matrix_oss: ${{ steps.vars.outputs.image_matrix_oss }}' | |
echo 'image_matrix_plus: ${{ steps.vars.outputs.image_matrix_plus }}' | |
echo 'image_matrix_nap: ${{ steps.vars.outputs.image_matrix_nap }}' | |
echo 'docker_build: ${{ steps.docker_build.outputs.docker_build }}' | |
verify-codegen: | |
name: Verify generated code | |
runs-on: ubuntu-24.04 | |
permissions: | |
contents: read | |
needs: checks | |
env: | |
GOPROXY: ${{ needs.checks.outputs.go_proxy }} | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
- name: Setup Golang Environment | |
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 | |
with: | |
go-version-file: go.mod | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' }} | |
- name: Setup netrc | |
run: | | |
cat <<EOF > $HOME/.netrc | |
machine azr.artifactory.f5net.com | |
login ${{ secrets.ARTIFACTORY_USER }} | |
password ${{ secrets.ARTIFACTORY_TOKEN }} | |
EOF | |
chmod 600 $HOME/.netrc | |
if: ${{ inputs.force || (needs.checks.outputs.binary_cache_hit != 'true' && needs.checks.outputs.forked_workflow != 'true') }} | |
- name: Check if go.mod and go.sum are up to date | |
run: go mod tidy && git diff --exit-code -- go.mod go.sum | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' }} | |
- name: Check if CRDs changed | |
run: make update-crds && git diff --name-only --exit-code config/crd/bases | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' }} | |
- name: Check if Codegen changed | |
run: | | |
cd ../.. && mkdir -p github.com/nginx && mv kubernetes-ingress/kubernetes-ingress github.com/nginx/ && cd github.com/nginx/kubernetes-ingress | |
make update-codegen && git diff --name-only --exit-code pkg/** | |
cd ../../.. && mv github.com/nginx/kubernetes-ingress kubernetes-ingress/kubernetes-ingress | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' }} | |
- name: Install gofumpt | |
run: go install mvdan.cc/[email protected] | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' }} | |
- name: Check if telemetry schema changed | |
run: | | |
export PATH=$PATH:$(go env GOPATH)/bin | |
make telemetry-schema && git diff --name-only --exit-code internal/telemetry | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' }} | |
unit-tests: | |
name: Unit Tests | |
runs-on: ubuntu-24.04 | |
needs: checks | |
env: | |
GOPROXY: ${{ needs.checks.outputs.go_proxy }} | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
- name: Setup Helm | |
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1 | |
with: | |
version: 'v3.18.6' | |
- name: Setup Golang Environment | |
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 | |
with: | |
go-version-file: go.mod | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' && (inputs.run_tests && inputs.run_tests || true) }} | |
- name: Setup netrc | |
run: | | |
cat <<EOF > $HOME/.netrc | |
machine azr.artifactory.f5net.com | |
login ${{ secrets.ARTIFACTORY_USER }} | |
password ${{ secrets.ARTIFACTORY_TOKEN }} | |
EOF | |
chmod 600 $HOME/.netrc | |
if: ${{ inputs.force || (needs.checks.outputs.binary_cache_hit != 'true' && needs.checks.outputs.forked_workflow != 'true') }} | |
- name: Run Tests | |
run: make cover | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' && (inputs.run_tests && inputs.run_tests || true) }} | |
- name: Upload coverage to Codecov | |
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 | |
with: | |
files: ./coverage.txt | |
token: ${{ secrets.CODECOV_TOKEN }} # required | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' && (inputs.run_tests && inputs.run_tests || true) }} | |
- name: Run static check | |
uses: dominikh/staticcheck-action@024238d2898c874f26d723e7d0ff4308c35589a2 # v1.4.0 | |
with: | |
version: "v0.6.0" | |
install-go: false | |
if: ${{ needs.checks.outputs.binary_cache_hit != 'true' && (inputs.run_tests && inputs.run_tests || true) }} | |
build-artifacts: | |
name: Build Artifacts | |
needs: [checks, unit-tests, verify-codegen] | |
uses: ./.github/workflows/build-artifacts.yml | |
with: | |
force: ${{ needs.checks.outputs.docker_build == 'true' || needs.checks.outputs.binary_cache_hit != 'true' }} | |
branch: ${{ (github.head_ref && needs.checks.outputs.forked_workflow != 'true') && github.head_ref || github.ref }} | |
tag: ${{ needs.checks.outputs.build_tag }} | |
docker-md5: ${{ needs.checks.outputs.docker_md5 }} | |
go-md5: ${{ needs.checks.outputs.go_code_md5 }} | |
go-path: ${{ needs.checks.outputs.go_path }} | |
go-proxy: ${{ needs.checks.outputs.go_proxy }} | |
image-matrix-oss: ${{ needs.checks.outputs.image_matrix_oss }} | |
image-matrix-plus: ${{ needs.checks.outputs.image_matrix_plus }} | |
image-matrix-nap: ${{ needs.checks.outputs.image_matrix_nap }} | |
ic-version: ${{ needs.checks.outputs.ic_version }} | |
authenticated: ${{ needs.checks.outputs.forked_workflow != 'true' }} | |
runner: ubuntu-24.04 | |
permissions: | |
contents: read | |
actions: read | |
id-token: write | |
packages: write | |
pull-requests: write # for scout report | |
secrets: inherit | |
# To pass the build in "Build Binaries" check | |
build-binaries: | |
name: Build Binaries | |
runs-on: ubuntu-24.04 | |
needs: [build-artifacts] | |
steps: | |
- name: Report build binaries status | |
run: echo "Build binaries completed successfully via build-artifacts job" | |
tag-target: | |
name: Tag untested image with PR number | |
needs: [checks, build-artifacts] | |
permissions: | |
contents: read # To checkout repository | |
id-token: write # To sign into Google Container Registry | |
uses: ./.github/workflows/retag-images.yml | |
with: | |
source_tag: ${{ needs.checks.outputs.build_tag }} | |
target_tag: ${{ needs.checks.outputs.additional_tag }} | |
dry_run: false | |
secrets: inherit | |
if: ${{ inputs.force || (needs.checks.outputs.forked_workflow == 'true' && needs.checks.outputs.docs_only == 'false') || (needs.checks.outputs.forked_workflow == 'false' && needs.checks.outputs.stable_image_exists != 'true' && needs.checks.outputs.docs_only == 'false') }} | |
package-tests: | |
if: ${{ needs.checks.outputs.docs_only != 'true' && (inputs.run_tests && inputs.run_tests || true) }} | |
name: Package Tests | |
runs-on: ubuntu-24.04 | |
needs: [checks, build-artifacts] | |
permissions: | |
contents: read | |
pull-requests: write # for package report | |
id-token: write | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
- name: Setup QEMU | |
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 | |
with: | |
platforms: arm64 | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Authenticate to Google Cloud | |
id: auth | |
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 | |
with: | |
token_format: access_token | |
workload_identity_provider: ${{ secrets.GCR_WORKLOAD_IDENTITY }} | |
service_account: ${{ secrets.GCR_SERVICE_ACCOUNT }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Login to GCR | |
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 | |
with: | |
registry: gcr.io | |
username: oauth2accesstoken | |
password: ${{ steps.auth.outputs.access_token }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Install Python dependencies | |
run: | | |
make -f tests/Makefile setup-venv | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Run tests | |
id: packages | |
run: | | |
source tests/venv/bin/activate | |
python tests/scripts/check_container_packages.py --tag ${{ needs.checks.outputs.build_tag }} --log package_output.txt | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Add comment | |
run: | | |
# make sure the comment is formatted correctly, as a code block | |
echo '### Package Report' > output.txt | |
echo '<details>' >> output.txt | |
cat package_output.txt | sed -r 's#^(.*)$#\1<br>#' >> output.txt | |
echo '</details>' >> output.txt | |
gh pr comment --edit-last --create-if-none ${{ github.event.pull_request.number }} -F output.txt | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
if: ${{ ( needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' ) && github.event.pull_request }} | |
helm-tests: | |
if: ${{ needs.checks.outputs.docs_only != 'true' && (inputs.run_tests && inputs.run_tests || true) }} | |
name: Helm Tests ${{ matrix.base-os }} | |
runs-on: ubuntu-24.04 | |
needs: [checks, build-artifacts] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- base-os: debian | |
image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress | |
tag: ${{ needs.checks.outputs.build_tag }} | |
type: oss | |
- base-os: debian-plus | |
image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress | |
tag: ${{ needs.checks.outputs.build_tag }} | |
type: plus | |
permissions: | |
contents: read | |
id-token: write | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
- name: Setup Helm | |
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1 | |
with: | |
version: 'v3.18.6' | |
- name: Authenticate to Google Cloud | |
id: auth | |
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 | |
with: | |
token_format: access_token | |
workload_identity_provider: ${{ secrets.GCR_WORKLOAD_IDENTITY }} | |
service_account: ${{ secrets.GCR_SERVICE_ACCOUNT }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Login to GCR | |
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 | |
with: | |
registry: gcr.io | |
username: oauth2accesstoken | |
password: ${{ steps.auth.outputs.access_token }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Check if stable image exists | |
id: stable_exists | |
run: | | |
if docker pull ${{ matrix.image }}:${{ needs.checks.outputs.stable_tag }}; then | |
echo "exists=true" >> $GITHUB_OUTPUT | |
fi | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' }} | |
- name: Pull build image | |
run: | | |
docker pull ${{ matrix.image }}:${{ needs.checks.outputs.build_tag }} | |
if: ${{ ( needs.checks.outputs.forked_workflow == 'false' || needs.checks.outputs.docs_only == 'false' ) && steps.stable_exists.outputs.exists != 'true' }} | |
- name: Fetch Cached Artifacts | |
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | |
with: | |
path: ${{ github.workspace }}/dist | |
key: nginx-ingress-${{ needs.checks.outputs.go_code_md5 }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Docker Buildx | |
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 | |
if: ${{ needs.checks.outputs.forked_workflow == 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Build Docker Image ${{ matrix.base-os }} | |
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 | |
with: | |
file: build/Dockerfile | |
context: "." | |
cache-from: type=gha,scope=${{ matrix.base-os }} | |
target: goreleaser | |
tags: "${{ matrix.image }}:${{ matrix.tag }}" | |
pull: true | |
load: true | |
build-args: | | |
BUILD_OS=${{ matrix.base-os }} | |
IC_VERSION=CI | |
secrets: | | |
${{ matrix.type == 'plus' && format('"nginx-repo.crt={0}"', secrets.NGINX_CRT) || '' }} | |
${{ matrix.type == 'plus' && format('"nginx-repo.key={0}"', secrets.NGINX_KEY) || '' }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Deploy Kubernetes | |
id: k8s | |
run: | | |
kind create cluster --name ${{ github.run_id }} --image=kindest/node:v${{ needs.checks.outputs.k8s_latest }} --wait 75s | |
docker version | |
kind load docker-image "${{ matrix.image }}:${{ matrix.tag }}" --name ${{ github.run_id }} | |
echo "DEBUG: Kind setup complete!" | |
if: ${{ steps.stable_exists.outputs.exists != 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Create Plus Secret | |
run: kubectl create secret generic license-token --from-literal=license.jwt="${{ secrets.PLUS_JWT }}" --type="nginx.com/license" | |
if: ${{ matrix.type == 'plus' && steps.stable_exists.outputs.exists != 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Install Chart | |
run: > | |
helm install | |
${{ matrix.type }} | |
. | |
--set controller.image.repository=${{ matrix.image }} | |
--set controller.image.tag=${{ matrix.tag }} | |
--set controller.service.type=NodePort | |
--set controller.nginxplus=${{ contains(matrix.type, 'plus') && 'true' || 'false' }} | |
--set controller.telemetryReporting.enable=false | |
--wait | |
working-directory: ${{ github.workspace }}/charts/nginx-ingress | |
if: ${{ steps.stable_exists.outputs.exists != 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Expose Test Ingresses | |
run: | | |
kubectl port-forward service/${{ matrix.type }}-nginx-ingress-controller 8080:80 8443:443 & | |
if: ${{ steps.stable_exists.outputs.exists != 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Test HTTP | |
run: | | |
counter=0 | |
max_attempts=5 | |
until [ $(curl --write-out %{http_code} -s --output /dev/null http://localhost:8080) -eq 404 ]; do | |
if [ ${counter} -eq ${max_attempts} ]; then | |
exit 1 | |
fi | |
printf '.'; counter=$(($counter+1)); sleep 5; | |
done | |
if: ${{ steps.stable_exists.outputs.exists != 'true' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Test HTTPS | |
run: | | |
counter=0 | |
max_attempts=5 | |
until [ $(curl --write-out %{http_code} -ks --output /dev/null https://localhost:8443) -eq 000 ]; do | |
if [ ${counter} -eq ${max_attempts} ]; then | |
exit 1 | |
fi | |
printf '.'; counter=$(($counter+1)); sleep 5; | |
done | |
if: ${{ steps.stable_exists.outputs.exists != 'true' && needs.checks.outputs.docs_only == 'false' }} | |
setup-matrix: | |
if: ${{ inputs.force || (inputs.run_tests && inputs.run_tests || true) || needs.checks.outputs.docs_only != 'true' }} | |
name: Setup Matrix for Smoke Tests | |
runs-on: ubuntu-24.04 | |
needs: [build-artifacts, checks] | |
permissions: | |
contents: read | |
id-token: write | |
outputs: | |
matrix_oss: ${{ steps.set-matrix.outputs.matrix_oss }} | |
matrix_plus: ${{ steps.set-matrix.outputs.matrix_plus }} | |
matrix_nap: ${{ steps.set-matrix.outputs.matrix_nap }} | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
- id: set-matrix | |
run: | | |
echo "matrix_oss=$(cat .github/data/matrix-smoke-oss.json | jq -c --arg latest "${{ needs.checks.outputs.k8s_latest }}" '.k8s += [$latest]')" >> $GITHUB_OUTPUT | |
echo "matrix_plus=$(cat .github/data/matrix-smoke-plus.json | jq -c --arg latest "${{ needs.checks.outputs.k8s_latest }}" '.k8s += [$latest]')" >> $GITHUB_OUTPUT | |
echo "matrix_nap=$(cat .github/data/matrix-smoke-nap.json | jq -c --arg latest "${{ needs.checks.outputs.k8s_latest }}" '.k8s += [$latest]')" >> $GITHUB_OUTPUT | |
- name: Docker Buildx | |
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 | |
- name: Authenticate to Google Cloud | |
id: auth | |
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 | |
with: | |
token_format: access_token | |
workload_identity_provider: ${{ secrets.GCR_WORKLOAD_IDENTITY }} | |
service_account: ${{ secrets.GCR_SERVICE_ACCOUNT }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Login to GCR | |
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 | |
with: | |
registry: gcr.io | |
username: oauth2accesstoken | |
password: ${{ steps.auth.outputs.access_token }} | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Check if test image exists | |
id: check-image | |
run: | | |
docker pull gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/test-runner:${{ hashFiles('./tests/requirements.txt', './tests/Dockerfile') || 'latest' }} | |
shell: bash | |
continue-on-error: true | |
if: ${{ needs.checks.outputs.forked_workflow == 'false' && needs.checks.outputs.docs_only == 'false' }} | |
- name: Build Test-Runner Container | |
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 | |
with: | |
file: tests/Dockerfile | |
context: "." | |
cache-from: type=gha,scope=test-runner | |
tags: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/test-runner:${{ hashFiles('./tests/requirements.txt', './tests/Dockerfile') || 'latest' }}" | |
pull: true | |
push: ${{ needs.checks.outputs.forked_workflow == 'false' }} | |
load: false | |
if: ${{ steps.check-image.outcome == 'failure' && needs.checks.outputs.docs_only == 'false' }} | |
smoke-tests-oss: | |
if: ${{ inputs.force || (inputs.run_tests && inputs.run_tests || true) || needs.checks.outputs.docs_only != 'true' }} | |
name: ${{ matrix.images.label }} ${{ matrix.images.image }} ${{ matrix.k8s }} smoke tests | |
needs: | |
- checks | |
- setup-matrix | |
- build-artifacts | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.setup-matrix.outputs.matrix_oss) }} | |
permissions: | |
contents: read | |
id-token: write | |
uses: ./.github/workflows/setup-smoke.yml | |
secrets: inherit | |
with: | |
image: ${{ matrix.images.image }} | |
target: ${{ matrix.images.target }} | |
nap-modules: ${{ matrix.images.nap_modules }} | |
marker: ${{ matrix.images.marker }} | |
label: ${{ matrix.images.label }} | |
go-md5: ${{ needs.checks.outputs.go_code_md5 }} | |
build-tag: ${{ needs.checks.outputs.build_tag }} | |
stable-tag: ${{ needs.checks.outputs.stable_tag }} | |
authenticated: ${{ needs.checks.outputs.forked_workflow != 'true' }} | |
k8s-version: ${{ matrix.k8s }} | |
force: ${{ inputs.run_tests && inputs.run_tests || true }} | |
smoke-tests-plus: | |
if: ${{ inputs.force || (inputs.run_tests && inputs.run_tests || true) || needs.checks.outputs.docs_only != 'true' }} | |
name: ${{ matrix.images.label }} ${{ matrix.images.image }} ${{ matrix.k8s }} smoke tests | |
needs: | |
- checks | |
- setup-matrix | |
- build-artifacts | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.setup-matrix.outputs.matrix_plus) }} | |
permissions: | |
contents: read | |
id-token: write | |
uses: ./.github/workflows/setup-smoke.yml | |
secrets: inherit | |
with: | |
image: ${{ matrix.images.image }} | |
target: ${{ matrix.images.target }} | |
nap-modules: ${{ matrix.images.nap_modules }} | |
marker: ${{ matrix.images.marker }} | |
label: ${{ matrix.images.label }} | |
go-md5: ${{ needs.checks.outputs.go_code_md5 }} | |
build-tag: ${{ needs.checks.outputs.build_tag }} | |
stable-tag: ${{ needs.checks.outputs.stable_tag }} | |
authenticated: ${{ needs.checks.outputs.forked_workflow != 'true' }} | |
k8s-version: ${{ matrix.k8s }} | |
force: ${{ inputs.run_tests && inputs.run_tests || true }} | |
smoke-tests-nap: | |
if: ${{ inputs.force || (inputs.run_tests && inputs.run_tests || true) || needs.checks.outputs.docs_only != 'true' }} | |
name: ${{ matrix.images.label }} ${{ matrix.images.image }} ${{ matrix.k8s }} smoke tests | |
needs: | |
- checks | |
- setup-matrix | |
- build-artifacts | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJSON(needs.setup-matrix.outputs.matrix_nap) }} | |
permissions: | |
contents: read | |
id-token: write | |
uses: ./.github/workflows/setup-smoke.yml | |
secrets: inherit | |
with: | |
image: ${{ matrix.images.image }} | |
target: ${{ matrix.images.target }} | |
nap-modules: ${{ matrix.images.nap_modules }} | |
marker: ${{ matrix.images.marker }} | |
label: ${{ matrix.images.label }} | |
go-md5: ${{ needs.checks.outputs.go_code_md5 }} | |
build-tag: ${{ needs.checks.outputs.build_tag }} | |
stable-tag: ${{ needs.checks.outputs.stable_tag }} | |
authenticated: ${{ needs.checks.outputs.forked_workflow != 'true' }} | |
k8s-version: ${{ matrix.k8s }} | |
force: ${{ inputs.run_tests && inputs.run_tests || true }} | |
tag-stable: | |
name: Tag tested image as stable | |
needs: [checks, build-artifacts, smoke-tests-oss, smoke-tests-plus, smoke-tests-nap] | |
permissions: | |
contents: read # To checkout repository | |
id-token: write # To sign into Google Container Registry | |
uses: ./.github/workflows/retag-images.yml | |
with: | |
source_tag: ${{ needs.checks.outputs.build_tag }} | |
target_tag: ${{ needs.checks.outputs.stable_tag }} | |
dry_run: false | |
secrets: inherit | |
if: ${{ inputs.force || (needs.checks.outputs.forked_workflow == 'true' && needs.checks.outputs.docs_only == 'false') || (needs.checks.outputs.forked_workflow == 'false' && needs.checks.outputs.stable_image_exists != 'true' && needs.checks.outputs.docs_only == 'false') }} | |
final-results: | |
if: ${{ !cancelled() }} | |
runs-on: ubuntu-24.04 | |
name: Final CI Results | |
needs: [tag-stable, build-artifacts, smoke-tests-oss, smoke-tests-plus, smoke-tests-nap, package-tests, helm-tests] | |
steps: | |
- run: | | |
tagResult="${{ needs.tag-stable.result }}" | |
packageResult="${{ needs.package-tests.result }}" | |
helmResult="${{ needs.helm-tests.result }}" | |
smokeOSSResult="${{ needs.smoke-tests-oss.result }}" | |
smokePlusResult="${{ needs.smoke-tests-plus.result }}" | |
smokeNAPResult="${{ needs.smoke-tests-nap.result }}" | |
buildArtifactsResult="${{ needs.build-artifacts.result }}" | |
if [[ $tagResult != "success" && $tagResult != "skipped" ]]; then | |
exit 1 | |
fi | |
if [[ $smokeOSSResult != "success" && $smokeOSSResult != "skipped" ]]; then | |
exit 1 | |
fi | |
if [[ $smokePlusResult != "success" && $smokePlusResult != "skipped" ]]; then | |
exit 1 | |
fi | |
if [[ $smokeNAPResult != "success" && $smokeNAPResult != "skipped" ]]; then | |
exit 1 | |
fi | |
if [[ $buildArtifactsResult != "success" && $buildArtifactsResult != "skipped" ]]; then | |
exit 1 | |
fi | |
if [[ $helmResult != "success" && $helmResult != "skipped" ]]; then | |
exit 1 | |
fi | |
if [[ $packageResult != "success" && $packageResult != "skipped" ]]; then | |
exit 1 | |
fi | |
trigger-image-promotion: | |
name: Promote images on Force Run | |
needs: | |
- final-results | |
- build-artifacts | |
permissions: | |
contents: write # for pushing to Helm Charts repository | |
id-token: write # To sign into Google Container Registry | |
actions: read | |
packages: write # for helm to push to GHCR | |
security-events: write | |
pull-requests: write # for scout report | |
uses: ./.github/workflows/image-promotion.yml | |
secrets: inherit | |
if: ${{ inputs.force }} |