Skip to content

Update peter-evans/dockerhub-description action to v5 (#8360) #1661

Update peter-evans/dockerhub-description action to v5 (#8360)

Update peter-evans/dockerhub-description action to v5 (#8360) #1661

name: Image Promotion
# This workflow will:
# - build images for forked workflows
# - tag stable for forked workflows
# - tag edge for main workflows
# - tag release branch name for release branch workflows
# - release edge images & helm charts for edge
# - run Trivy & dockerscout scans for main & release branch images
# & upload results to Github security & Github Artifacts
on:
push:
branches:
- main
- release-*
workflow_call:
defaults:
run:
shell: bash
concurrency:
group: ${{ github.ref_name }}-image-promotion
cancel-in-progress: true
permissions:
contents: read
jobs:
checks:
name: Checks and variables
runs-on: ubuntu-24.04-amd64
permissions:
contents: read
id-token: write
outputs:
go_path: ${{ steps.vars.outputs.go_path }}
go_code_md5: ${{ steps.vars.outputs.go_code_md5 }}
go_proxy: ${{ steps.vars.outputs.go_proxy }}
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 }}
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 }}
additional_tag: ${{ steps.vars.outputs.additional_tag }}
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
- name: Set Variables
id: vars
run: |
echo "go_path=$(go env GOPATH)" >> $GITHUB_OUTPUT
echo "go_proxy=${{ secrets.ARTIFACTORY_ENDPOINT }}" >> $GITHUB_OUTPUT
source .github/data/version.txt
echo "ic_version=${IC_VERSION}" >> $GITHUB_OUTPUT
echo "chart_version=${HELM_CHART_VERSION}" >> $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
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
REF=${{ github.ref_name }} ./.github/scripts/variables.sh additional_tag >> $GITHUB_OUTPUT
- 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 }}
- name: Login to GCR
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
registry: gcr.io
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}
- name: Output variables
run: |
echo go_code_md5: ${{ steps.vars.outputs.go_code_md5 }}
echo go_path: ${{ steps.vars.outputs.go_path }}
echo go_proxy: ${{ steps.vars.outputs.go_proxy }}
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 }}
govulncheck:
name: Run govulncheck
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
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
- 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
- name: govulncheck
uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1.0.4
with:
output-format: sarif
output-file: govulncheck.sarif
- name: Check SARIF file
id: check-sarif
run: |
if [ -s govulncheck.sarif ] && grep -q '"results":' govulncheck.sarif; then
echo "sarif_has_results=true" >> $GITHUB_OUTPUT
else
echo "sarif_has_results=false" >> $GITHUB_OUTPUT
fi
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
if: steps.check-sarif.outputs.sarif_has_results == 'true'
with:
sarif_file: govulncheck.sarif
build-artifacts:
name: Build Artifacts
needs: [checks]
uses: ./.github/workflows/build-artifacts.yml
with:
force: true
authenticated: true
ic-version: ${{ needs.checks.outputs.ic_version }}
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 }}
branch: ${{ github.ref }}
tag: ${{ needs.checks.outputs.build_tag }}
go-md5: ${{ needs.checks.outputs.go_code_md5 }}
docker-md5: ${{ needs.checks.outputs.docker_md5 }}
runner: "ubuntu-24.04-amd64"
secrets: inherit
permissions:
contents: read
actions: read
security-events: write
id-token: write
packages: write
pull-requests: write # for scout report
tag-stable:
name: Tag build image as stable
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.stable_tag }}
dry_run: false
secrets: inherit
tag-candidate:
# pushes edge or release images to gcr/dev
# for main: this keeps a copy of edge in gcr/dev
# for release-*: this stages a release candidate in gcr/dev which can be used for release promotion
name: Tag tested image as stable
needs:
- checks
- build-artifacts
- tag-stable
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.stable_tag }}
target_tag: ${{ github.ref_name == github.event.repository.default_branch && 'edge' || needs.checks.outputs.additional_tag }}
dry_run: false
secrets: inherit
if: ${{ !cancelled() && !failure() }}
release-oss:
# pushes edge images to docker hub
if: ${{ !cancelled() && !failure() && github.ref_name == github.event.repository.default_branch }}
name: Release Docker OSS
needs: [checks, build-artifacts]
uses: ./.github/workflows/oss-release.yml
with:
gcr_release_registry: false
ecr_public_registry: true
dockerhub_public_registry: true
quay_public_registry: true
github_public_registry: true
source_tag: ${{ needs.checks.outputs.stable_tag }}
target_tag: "edge"
branch: ${{ github.ref_name }}
dry_run: false
permissions:
contents: read
id-token: write
packages: write
secrets: inherit
release-plus:
# pushes plus edge images to nginx registry
if: ${{ !cancelled() && !failure() && github.ref_name == github.event.repository.default_branch }}
name: Release Docker Plus
needs: [checks, build-artifacts]
uses: ./.github/workflows/plus-release.yml
with:
nginx_registry: true
gcr_release_registry: false
gcr_mktpl_registry: false
ecr_mktpl_registry: false
az_mktpl_registry: false
source_tag: ${{ needs.checks.outputs.stable_tag }}
target_tag: "edge"
branch: ${{ github.ref_name }}
dry_run: false
permissions:
contents: read
id-token: write
secrets: inherit
publish-helm-chart:
if: ${{ !cancelled() && !failure() && github.ref_name == github.event.repository.default_branch }}
name: Publish Helm Chart
needs: [checks]
uses: ./.github/workflows/publish-helm.yml
with:
branch: ${{ github.ref_name }}
ic_version: edge
chart_version: 0.0.0-edge
nginx_helm_repo: false
runner: "ubuntu-24.04-amd64"
permissions:
contents: write # for pushing to Helm Charts repository
packages: write # for helm to push to GHCR
secrets: inherit
certify-openshift-images:
if: ${{ !cancelled() && !failure() && github.ref_name == github.event.repository.default_branch }}
name: Certify OpenShift UBI images
runs-on: ubuntu-24.04
needs: [release-oss]
steps:
- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Certify UBI OSS images in quay
uses: ./.github/actions/certify-openshift-image
continue-on-error: true
with:
image: quay.io/nginx/nginx-ingress:edge-ubi
project_id: ${{ secrets.CERTIFICATION_PROJECT_ID }}
pyxis_token: ${{ secrets.PYXIS_API_TOKEN }}
preflight_version: 1.14.1
scan-docker-oss:
name: Scan ${{ matrix.image }}
runs-on: ubuntu-24.04
needs: [checks, tag-candidate]
permissions:
contents: read
id-token: write
security-events: write
if: ${{ !cancelled() && !failure() }}
strategy:
fail-fast: false
matrix: ${{ fromJSON( needs.checks.outputs.image_matrix_oss ) }}
steps:
- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Make directory for security scan results
id: directory
run: |
directory=${{ matrix.image }}-results
echo "directory=${directory}" >> $GITHUB_OUTPUT
mkdir -p "${directory}"
- name: Docker meta
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
context: workflow
images: |
name=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress
flavor: |
suffix=${{ contains(matrix.image, 'ubi') && '-ubi' || '' }}${{ contains(matrix.image, 'alpine') && '-alpine' || '' }}
tags: |
type=raw,value=${{ github.ref_name == github.event.repository.default_branch && 'edge' || github.ref_name }}
- 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 }}
- name: Login to GCR
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
registry: gcr.io
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}
- name: DockerHub Login for Docker Scout
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Run Docker Scout vulnerability scanner
id: docker-scout
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1.18.2
with:
command: cves
image: ${{ steps.meta.outputs.tags }}
ignore-base: true
sarif-file: "${{ steps.directory.outputs.directory }}/scout.sarif"
write-comment: false
github-token: ${{ secrets.GITHUB_TOKEN }} # to be able to write the comment
summary: true
- name: Upload Scan Results to Github Artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: "${{ github.ref_name }}-${{ steps.directory.outputs.directory }}"
path: "${{ steps.directory.outputs.directory }}/"
overwrite: true
- name: Upload Scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
with:
sarif_file: "${{ steps.directory.outputs.directory }}/"
scan-docker-plus:
name: Scan ${{ matrix.image }}-${{ matrix.target }}
runs-on: ubuntu-24.04
needs: [checks, tag-candidate]
permissions:
contents: read
id-token: write
security-events: write
if: ${{ !cancelled() && !failure() }}
strategy:
fail-fast: false
matrix: ${{ fromJSON( needs.checks.outputs.image_matrix_plus ) }}
steps:
- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Make directory for security scan results
id: directory
run: |
directory=${{ matrix.image }}-${{ matrix.target }}-results
echo "directory=${directory}" >> $GITHUB_OUTPUT
mkdir -p "${directory}"
- name: Docker meta
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
context: workflow
images: |
name=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress
flavor: |
suffix=${{ contains(matrix.image, 'ubi') && '-ubi' || '' }}${{ contains(matrix.image, 'alpine') && '-alpine' || '' }}${{ contains(matrix.target, 'aws') && '-mktpl' || '' }}${{ contains(matrix.image, 'fips') && '-fips' || ''}}
tags: |
type=raw,value=${{ github.ref_name == github.event.repository.default_branch && 'edge' || github.ref_name }}
- 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 }}
- name: Login to GCR
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
registry: gcr.io
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}
- name: DockerHub Login for Docker Scout
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Run Docker Scout vulnerability scanner
id: docker-scout
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1.18.2
with:
command: cves
image: ${{ steps.meta.outputs.tags }}
ignore-base: true
sarif-file: "${{ steps.directory.outputs.directory }}/scout.sarif"
write-comment: false
github-token: ${{ secrets.GITHUB_TOKEN }} # to be able to write the comment
summary: true
- name: Upload Scan Results to Github Artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: "${{ github.ref_name }}-${{ steps.directory.outputs.directory }}"
path: "${{ steps.directory.outputs.directory }}/"
overwrite: true
- name: Upload Scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
with:
sarif_file: "${{ steps.directory.outputs.directory }}/"
scan-docker-nap:
name: Scan ${{ matrix.image }}-${{ matrix.target }}-${{ matrix.nap_modules }}
runs-on: ubuntu-24.04
needs: [checks, tag-candidate]
permissions:
contents: read
id-token: write
security-events: write
if: ${{ !cancelled() && !failure() }}
strategy:
fail-fast: false
matrix: ${{ fromJSON( needs.checks.outputs.image_matrix_nap ) }}
steps:
- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: NAP modules
id: nap_modules
run: |
[[ "${{ matrix.nap_modules }}" == "waf,dos" ]] && modules="waf-dos" || name="${{ matrix.nap_modules }}"
echo "name=${name}" >> $GITHUB_OUTPUT
if: ${{ matrix.nap_modules != '' }}
- name: Make directory for security scan results
id: directory
run: |
directory=${{ matrix.image }}-${{ matrix.target }}-${{ steps.nap_modules.outputs.name }}-results
echo "directory=${directory}" >> $GITHUB_OUTPUT
mkdir -p "${directory}"
- name: Docker meta
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
context: workflow
images: |
name=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic${{ contains(matrix.nap_modules, 'dos') && '-dos' || '' }}${{ contains(matrix.nap_modules, 'waf') && '-nap' || '' }}${{ contains(matrix.image, 'v5') && '-v5' || '' }}/nginx-plus-ingress
flavor: |
suffix=${{ contains(matrix.image, 'ubi') && '-ubi' || '' }}${{ contains(matrix.image, 'alpine') && '-alpine' || '' }}${{ contains(matrix.target, 'aws') && '-mktpl' || '' }}${{ contains(matrix.image, 'fips') && '-fips' || ''}}
tags: |
type=raw,value=${{ github.ref_name == github.event.repository.default_branch && 'edge' || github.ref_name }}
- 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 }}
- name: Login to GCR
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
registry: gcr.io
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}
- name: DockerHub Login for Docker Scout
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Run Docker Scout vulnerability scanner
id: docker-scout
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1.18.2
with:
command: cves
image: ${{ steps.meta.outputs.tags }}
ignore-base: true
sarif-file: "${{ steps.directory.outputs.directory }}/scout.sarif"
write-comment: false
github-token: ${{ secrets.GITHUB_TOKEN }} # to be able to write the comment
summary: true
- name: Upload Scan Results to Github Artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: "${{ github.ref_name }}-${{ steps.directory.outputs.directory }}"
path: "${{ steps.directory.outputs.directory }}/"
overwrite: true
- name: Upload Scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
with:
sarif_file: "${{ steps.directory.outputs.directory }}/"
continue-on-error: true
update-release-draft:
name: Update Release Draft
runs-on: ubuntu-24.04
needs: [checks]
permissions:
contents: write
steps:
- name: Checkout Repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Create/Update Draft
uses: lucacome/draft-release@00f74370c044c322da6cb52acc707d62c7762c71 # v1.2.4
id: release-notes
with:
minor-label: "enhancement"
major-label: "change"
publish: false
collapse-after: 50
variables: |
helm-chart=${{ needs.checks.outputs.chart_version }}
notes-footer: |
## Upgrade
- For NGINX, use the {{version}} images from our [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/tags?page=1&ordering=last_updated&name={{version-number}}), [GitHub Container](https://github.com/nginx/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress).
- For NGINX Plus, use the {{version}} images from the F5 Container registry or build your own image using the {{version}} source code.
- For Helm, use version {{helm-chart}} of the chart.
## Resources
- Documentation -- https://docs.nginx.com/nginx-ingress-controller/
- Configuration examples -- https://github.com/nginx/kubernetes-ingress/tree/{{version}}/examples
- Helm Chart -- https://github.com/nginx/kubernetes-ingress/tree/{{version}}/deployments/helm-chart
- Operator -- https://github.com/nginx/nginx-ingress-helm-operator
if: ${{ github.event_name == 'push' && contains(github.ref_name, 'release-') }}