diff --git a/.github/workflows/_charm-quality-checks.yaml b/.github/workflows/_charm-quality-checks.yaml
index 4d4b2314..41f8c843 100644
--- a/.github/workflows/_charm-quality-checks.yaml
+++ b/.github/workflows/_charm-quality-checks.yaml
@@ -7,6 +7,17 @@ on:
type: string
required: false
default: .
+ log-path:
+ type: string
+ description: |
+ Path to a directory where the .txt log files for an integration testing run will be stored.
+ Relative and absolute file paths are both allowed.
+ Relative paths are rooted against the charm directory specified by `charm-path`
+ (which defaults to the repository root, `.`).
+ Paths that begin with a wildcard character should be quoted to avoid being
+ interpreted as YAML aliases.
+ required: false
+ default: .logs
provider:
type: string
description: "The provider to choose for integration tests ('machine', 'microk8s', or 'k8s')"
@@ -273,6 +284,43 @@ jobs:
CHARM_PATH="$(realpath "$charm_relative_path")"
export CHARM_PATH
uvx tox -e integration
+ - name: Determine log files location
+ if: always()
+ id: get_log_path
+ env:
+ LOG_PATH: ${{ inputs.log-path }}
+ CHARM_PATH: ${{ inputs.charm-path }}
+ run: |
+ # if the user gave us a relative path, interpret it from the charm-path root.
+ # if path starts with / it's absolute, else it's relative, and we prepend the (absolute) charm-path to it
+ case "$LOG_PATH" in
+ /*) log_path="$LOG_PATH" ;;
+ *) log_path="$CHARM_PATH/$LOG_PATH" ;;
+ esac
+ echo "log path is: $log_path"
+ echo "log_path=$log_path" >> "$GITHUB_OUTPUT"
+ - name: Show logs
+ if: always()
+ env:
+ LOG_DIR: ${{ steps.get_log_path.outputs.log_path }}
+ run: |
+ if test -d "$LOG_DIR"; then
+ shopt -s nullglob
+ for filename in "$LOG_DIR"/*.txt; do
+ printf '\n::group:: %s\n' "$filename"
+ cat "$filename"
+ printf "\n::endgroup::\n"
+ done
+ else
+ echo "$LOG_DIR not found"
+ fi
+ - name: Upload logs
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: charm-logs${{ (inputs.charm-path && inputs.charm-path != '.') && format('-{0}', inputs.charm-path) || '' }}
+ include-hidden-files: true
+ path: ${{ steps.get_log_path.outputs.log_path }}
integration-matrix:
name: Define Integration tests matrix
@@ -403,3 +451,45 @@ jobs:
with:
timeout-minutes: 30
limit-access-to-actor: true
+ - name: Determine log files location
+ if: always()
+ id: get_log_path
+ env:
+ LOG_PATH: ${{ inputs.log-path }}
+ CHARM_PATH: ${{ inputs.charm-path }}
+ run: |
+ # if the user gave us a relative path, interpret it from the charm-path root.
+ # if path starts with / it's absolute, else it's relative, and we prepend the (absolute) charm-path to it
+ case "$LOG_PATH" in
+ /*) log_path="$LOG_PATH" ;;
+ *) log_path="$CHARM_PATH/$LOG_PATH" ;;
+ esac
+ echo "log path is: $log_path"
+ echo "log_path=$log_path" >> "$GITHUB_OUTPUT"
+ - name: Show logs
+ if: always()
+ env:
+ LOG_DIR: ${{ steps.get_log_path.outputs.log_path }}
+ run: |
+ if test -d "$LOG_DIR"; then
+ shopt -s nullglob
+ for filename in "$LOG_DIR"/*.txt; do
+ # begin collapsible log group for each file found in the folder;
+ # this is github CI markup
+ # cfr: https://github.com/go-task/task/issues/647
+ printf '\n::group:: %s\n' "$filename"
+ cat "$filename"
+ printf "\n::endgroup::\n"
+ done
+ else
+ echo "$LOG_DIR not found"
+ fi
+ - name: Upload logs
+ if: always()
+ uses: actions/upload-artifact@v4
+ # defaults to 'warn' on failure
+ with:
+ name: charm-logs${{ (inputs.charm-path && inputs.charm-path != '.') && format('-{0}', inputs.charm-path) || '' }}-${{ matrix.suite }}
+ include-hidden-files: true
+ # we assume that log_path is never going to be an empty string; but it may well be a non-existing directory.
+ path: ${{ steps.get_log_path.outputs.log_path }}
diff --git a/.github/workflows/charm-pull-request.yaml b/.github/workflows/charm-pull-request.yaml
index 50d00ebd..b1996826 100644
--- a/.github/workflows/charm-pull-request.yaml
+++ b/.github/workflows/charm-pull-request.yaml
@@ -8,6 +8,16 @@ on:
default: '.'
required: false
type: string
+ log-path:
+ type: string
+ description: |
+ Path to a directory where the .txt log files for an integration testing run will be stored.
+ Relative and absolute file paths are both allowed.
+ Relative paths are resolved relative to `charm-path`.
+ Paths that begin with a wildcard character should be quoted to avoid being
+ interpreted as YAML aliases.
+ required: false
+ default: .logs
provider:
description: "The provider to choose for either machine or k8s tests ('machine', 'microk8s', or 'k8s')"
default: 'k8s'
@@ -128,6 +138,7 @@ jobs:
secrets: inherit
with:
charm-path: ${{ inputs.charm-path }}
+ log-path: ${{ inputs.log-path }}
provider: ${{ inputs.provider }}
charmcraft-channel: ${{ inputs.charmcraft-channel }}
juju-channel: ${{ inputs.juju-channel }}
diff --git a/README.md b/README.md
index fae655c8..4da78ee6 100644
--- a/README.md
+++ b/README.md
@@ -60,9 +60,11 @@ block-beta
qualitychecksslow["Quality Checks (integration)"]
pack["Pack the charm"]
integration["Integration tests"]
+ displaylogs["Display logs"]
+ uploadlogs["Upload logs zip file"]
+ integration --> displaylogs --> uploadlogs
end
-
block
columns 1
release["Release Charm (per arch)"]