Skip to content

Update integration_test.yaml #16

Update integration_test.yaml

Update integration_test.yaml #16

# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.
name: Integration tests
on:
workflow_call:
inputs:
charmcraft-channel:
description: Charmcraft channel to use for the integration test
type: string
default: latest/stable
charmcraft-ref:
description: Used in conjunction with charmcraft-repository to pull and build charmcraft from source instead of using snapstore version.
type: string
default: ""
charmcraft-repository:
description: Pull and build charmcraft from source instead of using snapstore version (this means that the `charmcraft-channel` input will be ignored).
type: string
default: ""
channel:
description: Actions operator provider channel as per https://github.com/charmed-kubernetes/actions-operator#usage
type: string
default: latest/stable
charm-directory:
type: string
description: The directory for the charm under the working-directory
default: "."
extra-arguments:
description: Additional arguments to pass to the integration test execution
type: string
extra-test-matrix:
description: |
Aditional mapping to lists of matrices to be applied on top of series and modules matrix in JSON format, i.e. '{"extras":["foo","bar"]}'.
Each mapping will be injected into the matrix section of the integration-test.
type: string
default: "{}"
image-build-args:
description: |
List of build args to pass to the build image job
type: string
default: ""
juju-channel:
description: Actions operator juju channel as per https://github.com/charmed-kubernetes/actions-operator#usage
type: string
default: 2.9/stable
load-test-enabled:
type: boolean
description: Whether load testing is enabled
default: false
load-test-run-args:
type: string
description: Command line arguments for the load test execution
default: ""
modules:
description: List of testing modules to run the tests in JSON format, i.e. '["foo", "bar"]'. Each element will be passed to pytest through tox as -k argument
type: string
default: '[""]'
pre-run-script:
description: Path to the bash script to be run before the integration tests
type: string
provider:
description: Actions operator provider as per https://github.com/charmed-kubernetes/actions-operator#usage
type: string
default: microk8s
rockcraft-channel:
description: Rockcraft channel to use for the integration test
type: string
default: latest/stable
rockcraft-ref:
description: Used in conjunction with rockcraft-repository to pull and build rockcraft from source instead of using snapstore version.
type: string
default: ""
rockcraft-repository:
description: Pull and build rockcraft from source instead of using snapstore version (this means that the rockcraft-channel input will be ignored).
type: string
default: ""
microk8s-addons:
description: Microk8s provider add-ons override. A minimum set of addons (the defaults) must be enabled.
type: string
default: "dns ingress rbac storage"
self-hosted-runner:
type: boolean
description: Whether to use self-hosted runners to run the jobs.
default: false
self-hosted-runner-label:
type: string
description: Label for selecting the self-hosted runners.
default: "large"
series:
description: List of series to run the tests in JSON format, i.e. '["jammy", "focal"]'. Each element will be passed to pytest through tox as --series argument
type: string
default: '[""]'
setup-devstack-swift:
description: Use setup-devstack-swift action to prepare a swift server for testing.
type: boolean
default: false
test-timeout:
description: Timeout in minutes for the integration test.
type: number
default: 360
test-tox-env:
description: The tox environment name for the integration test.
type: string
default: "integration"
tmate-debug:
description: Use tmate debugging session on integration test failure.
type: boolean
default: false
tmate-timeout:
description: Timeout in minutes to keep tmate debugging session.
type: number
default: 30
trivy-fs-config:
type: string
description: Trivy YAML configuration for fs testing that is checked in as part of the repo
trivy-fs-enabled:
type: boolean
description: Whether Trivy testing of type fs is enabled
default: false
trivy-fs-ref:
type: string
description: Target directory to do the Trivy testing
default: "."
trivy-image-config:
type: string
description: Trivy YAML configuration for image testing that is checked in as part of the repo
working-directory:
type: string
description: The working directory for jobs
default: "./"
zap-auth-header:
description: If this is defined then its value will be added as a header to all of the ZAP requests
type: string
zap-auth-header-value:
description: If this is defined then its value will be used as the header name to all of the ZAP requests
type: string
zap-before-command:
description: Command to run before ZAP testing
type: string
zap-cmd-options:
description: Options to be used by ZAP
type: string
default: "-T 60"
zap-enabled:
type: boolean
description: Whether ZAP testing is enabled
default: false
zap-target:
description: If this is not set, the unit IP address will be used as ZAP target
type: string
zap-target-port:
description: ZAP target port
type: string
default: 80
zap-target-protocol:
description: ZAP target protocol
type: string
default: "http"
zap-rules-file-name:
description: Rules file to ignore any alerts from the ZAP scan
type: string
outputs:
images:
description: Pushed images
value: ${{ jobs.all-images.outputs.images }}
env:
REGISTRY: ghcr.io
OWNER: ${{ github.repository_owner }}
concurrency:
group: operator-workflows-${{ github.workflow }}-integration-tests-${{ github.ref }}-${{ inputs.test-tox-env }}
cancel-in-progress: true
jobs:
plan:
name: Plan
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- uses: >-
${{
github.event.repository.name == 'operator-workflows' &&
format('{0}/internal/plan@{1}', github.event.pull_request.head.repo.full_name, github.head_ref) ||
'canonical/operator-workflows/internal/plan@main'
}}
with:
working-directory: ${{ inputs.working-directory }}
get-runner-image:
name: Get runner image
uses: ./.github/workflows/get_runner_image.yaml
with:
working-directory: ${{ inputs.working-directory }}
build-images:
name: Build image
uses: ./.github/workflows/build_images.yaml
needs: get-runner-image
with:
owner: ${{ github.repository_owner }}
registry: ghcr.io
runs-on: ${{ needs.get-runner-image.outputs.runs-on }}
trivy-image-config: ${{ inputs.trivy-image-config }}
working-directory: ${{ inputs.working-directory }}
build-args: ${{ inputs.image-build-args }}
build-rocks:
name: Build rock
uses: ./.github/workflows/build_rocks.yaml
needs: get-runner-image
with:
owner: ${{ github.repository_owner }}
registry: ghcr.io
runs-on: ${{ needs.get-runner-image.outputs.runs-on }}
trivy-image-config: ${{ inputs.trivy-image-config }}
working-directory: ${{ inputs.working-directory }}
rockcraft-channel: ${{ inputs.rockcraft-channel }}
rockcraft-repository: ${{ inputs.rockcraft-repository }}
rockcraft-ref: ${{ inputs.rockcraft-ref }}
all-images:
name: Get rocks or Docker images
needs: [ build-images, build-rocks ]
runs-on: ubuntu-latest
outputs:
images: ${{ env.IMAGES }}
steps:
- name: Get rocks or fallback to Docker images
run: |
if [ ${{ needs.build-rocks.outputs.images != '[]' }} = true ]; then
IMAGES='${{ needs.build-rocks.outputs.images }}'
else
IMAGES='${{ needs.build-images.outputs.images }}'
fi
echo "IMAGES=$IMAGES" >> $GITHUB_ENV
build-charm:
name: Build and push charm
needs: get-runner-image
runs-on: ${{ needs.get-runner-image.outputs.runs-on }}
outputs:
charm-file: ${{ env.CHARM_FILE }}
steps:
- uses: canonical/[email protected]
- uses: actions/checkout@v4
if: inputs.charmcraft-repository != ''
with:
repository: ${{ inputs.charmcraft-repository }}
ref: ${{ inputs.charmcraft-ref }}
path: ./charmcraft
fetch-depth: 0
- name: Get Charmcraft SHA
if: inputs.charmcraft-repository != ''
id: charmcraft-sha
working-directory: ./charmcraft
run: echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Restore Charmcraft Cache
if: inputs.charmcraft-repository != ''
id: restore-charmcraft
uses: actions/cache/restore@v4
with:
path: ./charmcraft*.snap
key: charmcraft-${{ steps.charmcraft-sha.outputs.sha }}
- name: Install Snapcraft
if: steps.restore-charmcraft.outputs.cache-hit != 'true' && inputs.charmcraft-repository != ''
run: sudo snap install snapcraft --classic
- name: Build Charmcraft
if: steps.restore-charmcraft.outputs.cache-hit != 'true' && inputs.charmcraft-repository != ''
working-directory: ./charmcraft
run: |
snapcraft --use-lxd
cp charmcraft*.snap ../
- name: Save Charmcraft Cache
uses: actions/cache/save@v4
if: steps.restore-charmcraft.outputs.cache-hit != 'true' && inputs.charmcraft-repository != ''
with:
path: ./charmcraft*.snap
key: ${{ steps.restore-charmcraft.outputs.cache-primary-key }}
- name: Install charmcraft
if: inputs.charmcraft-repository != ''
run: sudo snap install --dangerous --classic charmcraft*.snap
- name: Clean up
if: inputs.charmcraft-repository != ''
run: rm -rf *
- name: Install charmcraft
if: inputs.charmcraft-repository == ''
run: |
sudo snap install charmcraft --classic --channel ${{ inputs.charmcraft-channel }}
- uses: actions/[email protected]
- name: Get charm dir
working-directory: ${{ inputs.working-directory }}
run: echo "CHARM_DIR=$([ -d charm ] && realpath charm || realpath .)">> $GITHUB_ENV
- name: Extract charm name
working-directory: ${{ env.CHARM_DIR }}
run: |
CHARM_NAME="$([ -f metadata.yaml ] && yq '.name' metadata.yaml || echo UNKNOWN)"
if [ "$CHARM_NAME" == "UNKNOWN" ]; then
CHARM_NAME="$([ -f charmcraft.yaml ] && yq '.name' charmcraft.yaml || echo UNKNOWN)"
fi
echo "CHARM_NAME=$CHARM_NAME">> $GITHUB_ENV
- name: Pack charm
if: ${{ env.CHARM_NAME != 'UNKNOWN' && !cancelled() }}
working-directory: ${{ env.CHARM_DIR }}
env:
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS: "true"
run: |
charmcraft pack -v
echo "CHARM_FILE=$(ls $CHARM_NAME_*.charm || echo UNKNOWN)" >> $GITHUB_ENV
- name: Upload charm artifact
if: ${{ !contains(fromJson('["", "UNKNOWN"]'), env.CHARM_FILE) && !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: ${{ env.CHARM_NAME }}-charm
path: ${{ env.CHARM_DIR }}/${{ env.CHARM_FILE }}
if-no-files-found: error
overwrite: true
- name: Save image names for charm OCI resources
if: ${{ always() && env.CHARM_NAME != 'UNKNOWN' && !cancelled() }}
working-directory: ${{ env.CHARM_DIR }}
run: |
echo "$(echo '${{ needs.all-images.outputs.images }}' | jq -cr '.[]')" > ${{ env.CHARM_NAME }}-images
- name: Upload image artifact
if: ${{ always() && env.CHARM_NAME != 'UNKNOWN' && !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: ${{ env.CHARM_NAME }}-images
path: ${{ env.CHARM_DIR }}/${{ env.CHARM_NAME }}-images
if-no-files-found: error
overwrite: true
integration-test:
name: Integration tests
uses: ./.github/workflows/integration_test_run.yaml
needs: [ all-images, build-charm, get-runner-image ]
if: ${{ !failure() }}
secrets: inherit
with:
channel: ${{ inputs.channel }}
charm-file: ${{ needs.build-charm.outputs.charm-file }}
charmcraft-ref: ${{ inputs.charmcraft-ref }}
charmcraft-repository: ${{ inputs.charmcraft-repository }}
charm-directory: ${{ inputs.charm-directory }}
extra-arguments: ${{ inputs.extra-arguments }}
extra-test-matrix: ${{ inputs.extra-test-matrix }}
images: ${{ needs.all-images.outputs.images }}
juju-channel: ${{ inputs.juju-channel }}
load-test-enabled: ${{ inputs.load-test-enabled }}
load-test-run-args: ${{ inputs.load-test-run-args }}
microk8s-addons: ${{ inputs.microk8s-addons }}
modules: ${{ inputs.modules }}
owner: ${{ github.repository_owner }}
pre-run-script: ${{ inputs.pre-run-script }}
provider: ${{ inputs.provider }}
registry: ghcr.io
runs-on: ${{ needs.get-runner-image.outputs.runs-on }}
self-hosted-runner-label: ${{ inputs.self-hosted-runner-label }}
self-hosted-runner: ${{ inputs.self-hosted-runner }}
series: ${{ inputs.series }}
setup-devstack-swift: ${{ inputs.setup-devstack-swift }}
test-timeout: ${{ inputs.test-timeout }}
test-tox-env: ${{ inputs.test-tox-env }}
tmate-debug: ${{ inputs.tmate-debug }}
tmate-timeout: ${{ inputs.tmate-timeout }}
trivy-fs-config: ${{ inputs.trivy-fs-config }}
trivy-fs-enabled: ${{ inputs.trivy-fs-enabled }}
trivy-fs-ref: ${{ inputs.trivy-fs-ref }}
working-directory: ${{ inputs.working-directory }}
zap-auth-header-value: ${{ inputs.zap-auth-header-value }}
zap-auth-header: ${{ inputs.zap-auth-header }}
zap-before-command: ${{ inputs.zap-before-command }}
zap-cmd-options: ${{ inputs.zap-cmd-options }}
zap-enabled: ${{ inputs.zap-enabled }}
zap-rules-file-name: ${{ inputs.zap-rules-file-name }}
zap-target-port: ${{ inputs.zap-target-port }}
zap-target-protocol: ${{ inputs.zap-target-protocol }}
zap-target: ${{ inputs.zap-target }}
required_status_checks:
name: Required Integration Test Status Checks
runs-on: ubuntu-latest
needs:
- integration-test
if: always() && !cancelled()
timeout-minutes: 5
steps:
- run: |
[ '${{ needs.integration-test.result }}' = 'success' ] || (echo integration-test failed && false)