Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/workflows/_resolve-charm-paths.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Resolve Charm Paths

on:
workflow_call:
inputs:
charm-path:
description: |
Path to the charm. Defaults to the current working directory.
If 'charm-paths' is also provided, 'charm-paths' takes precedence.
default: '.'
required: false
type: string
charm-paths:
description: |
JSON list of charm paths (e.g. '["charms/foo", "charms/bar"]').
If provided, takes precedence over 'charm-path'.
default: ''
required: false
type: string
filter-by-changes:
description: |
When 'charm-paths' is provided and this is true, only charms with
file changes will be included in the matrix (using dorny/paths-filter).
required: true
type: boolean
outputs:
charm-paths:
description: "JSON list of resolved charm paths"
value: ${{ jobs.resolve.outputs.charm-paths }}

jobs:
resolve:
name: Resolve charm paths
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
charm-paths: ${{ steps.set-paths.outputs.charm-paths }}
steps:
- name: Checkout repository
if: ${{ inputs.filter-by-changes }}
uses: actions/checkout@v6
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
fetch-depth: 0

- name: Resolve effective charm paths
id: resolve
env:
CHARM_PATH: ${{ inputs.charm-path }}
CHARM_PATHS: ${{ inputs.charm-paths }}
run: |
if [[ -n "$CHARM_PATHS" ]]; then
echo "all-paths=$CHARM_PATHS" >> "$GITHUB_OUTPUT"
else
echo "all-paths=[\"$CHARM_PATH\"]" >> "$GITHUB_OUTPUT"
fi

- name: Generate path filters config
if: ${{ inputs.charm-paths != '' && inputs.filter-by-changes }}
id: generate-filters
env:
CHARM_PATHS: ${{ steps.resolve.outputs.all-paths }}
run: |
filters=""
while IFS= read -r path; do
printf -v filters '%s%s:\n - %s/**\n' "$filters" "$path" "$path"
done < <(echo "$CHARM_PATHS" | jq -r '.[]')
{
echo "filters<<EOF"
printf '%s\n' "$filters"
echo "EOF"
} >> "$GITHUB_OUTPUT"

- name: Filter by changes
if: ${{ inputs.charm-paths != '' && inputs.filter-by-changes }}
id: filter
uses: dorny/paths-filter@v3
with:
filters: ${{ steps.generate-filters.outputs.filters }}

- name: Set final charm paths
id: set-paths
env:
ALL_PATHS: ${{ steps.resolve.outputs.all-paths }}
FILTER_ENABLED: ${{ inputs.charm-paths != '' && inputs.filter-by-changes }}
CHANGED_PATHS: ${{ steps.filter.outputs.changes }}
run: |
if [[ "$FILTER_ENABLED" == "true" && -n "$CHANGED_PATHS" ]]; then
echo "charm-paths=$CHANGED_PATHS" >> "$GITHUB_OUTPUT"
elif [[ "$FILTER_ENABLED" == "true" ]]; then
echo "charm-paths=[]" >> "$GITHUB_OUTPUT"
else
echo "charm-paths=$ALL_PATHS" >> "$GITHUB_OUTPUT"
fi
28 changes: 25 additions & 3 deletions .github/workflows/charm-promote.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ on:
workflow_call:
inputs:
charm-path:
description: "Path to the charm we want to promote. Defaults to the current working directory."
description: |
Path to the charm we want to promote. Defaults to the current working directory.
If 'charm-paths' is also provided, 'charm-paths' takes precedence and this input is ignored.
type: string
default: '.'
required: false
charm-paths:
description: |
JSON list of charm paths (e.g. '["charms/foo", "charms/bar"]').
If provided, takes precedence over 'charm-path'.
Each path will be processed as a separate matrix entry.
default: ''
required: false
type: string
promotion:
type: string
required: true
Expand All @@ -21,9 +31,21 @@ on:
required: true

jobs:
resolve-charm-paths:
uses: canonical/observability/.github/workflows/_resolve-charm-paths.yaml@v1
with:
charm-path: ${{ inputs.charm-path }}
charm-paths: ${{ inputs.charm-paths }}
filter-by-changes: false

promote:
name: Promote Charm
name: Promote Charm (${{ matrix.charm-path }})
needs: [resolve-charm-paths]
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
charm-path: ${{ fromJSON(needs.resolve-charm-paths.outputs.charm-paths) }}
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down Expand Up @@ -53,7 +75,7 @@ jobs:
- name: Promote charm
env:
CHARMCRAFT_AUTH: ${{ secrets.CHARMHUB_TOKEN }}
CHARM_PATH: "${{ inputs.charm-path }}"
CHARM_PATH: "${{ matrix.charm-path }}"
run: |
# Read the charm name from charmcraft.yaml / metadata.yaml
cd "$CHARM_PATH"
Expand Down
50 changes: 41 additions & 9 deletions .github/workflows/charm-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,27 @@ on:
workflow_call:
inputs:
charm-path:
description: "Path to the charm we want to publish. Defaults to the current working directory."
description: |
Path to the charm we want to publish. Defaults to the current working directory.
If 'charm-paths' is also provided, 'charm-paths' takes precedence and this input is ignored.
default: '.'
required: false
type: string
charm-paths:
description: |
JSON list of charm paths (e.g. '["charms/foo", "charms/bar"]').
If provided, takes precedence over 'charm-path'.
Each path will be processed as a separate matrix entry.
default: ''
required: false
type: string
filter-by-changes:
description: |
When 'charm-paths' is provided and this is true, only charms with
file changes will be included in the matrix (using dorny/paths-filter).
default: true
required: false
type: boolean
provider:
description: "The provider to choose for either machine or k8s tests ('machine', 'microk8s', or 'k8s')"
default: 'k8s'
Expand Down Expand Up @@ -55,6 +72,13 @@ concurrency:
cancel-in-progress: true

jobs:
resolve-charm-paths:
uses: canonical/observability/.github/workflows/_resolve-charm-paths.yaml@v1
with:
charm-path: ${{ inputs.charm-path }}
charm-paths: ${{ inputs.charm-paths }}
filter-by-changes: ${{ inputs.filter-by-changes }}

ci-ignore:
name: Check against ignorelist
runs-on: ubuntu-latest
Expand Down Expand Up @@ -89,12 +113,16 @@ jobs:
echo "any_modified=${{ steps.changed-files.outputs.any_modified }}" >> "$GITHUB_OUTPUT"

lib-check:
name: Check libraries # Check if the charm libraries are updated and add the relevant label to the PR
name: Check libraries (${{ matrix.charm-path }}) # Check if the charm libraries are updated and add the relevant label to the PR
runs-on: ubuntu-latest
needs: [ci-ignore]
needs: [resolve-charm-paths, ci-ignore]
# NOTE: This job doesn't run on forks, as they wouldn't have the necessary secret to
# update the PR labels.
if: ${{ github.event_name == 'pull_request' && needs.ci-ignore.outputs.any_modified == 'true' && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }}
if: ${{ github.event_name == 'pull_request' && needs.resolve-charm-paths.outputs.charm-paths != '[]' && needs.ci-ignore.outputs.any_modified == 'true' && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }}
strategy:
fail-fast: false
matrix:
charm-path: ${{ fromJSON(needs.resolve-charm-paths.outputs.charm-paths) }}
steps:
- name: Checkout
uses: actions/checkout@v6
Expand All @@ -110,7 +138,7 @@ jobs:
CHARMCRAFT_AUTH: ${{ secrets.CHARMHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
run: |
cd "${{ inputs.charm-path }}"
cd "${{ matrix.charm-path }}"
fetch_lib="$(charmcraft fetch-lib)"
# If charm libraries are not up-to-date
if echo "$fetch_lib" | grep -qE "not found in Charmhub|updated to version|has local changes"; then
Expand All @@ -120,18 +148,22 @@ jobs:
fi

quality-checks:
name: Quality Checks
name: Quality Checks (${{ matrix.charm-path }})
needs:
- resolve-charm-paths
- ci-ignore
if: needs.ci-ignore.outputs.any_modified == 'true'
if: ${{ needs.resolve-charm-paths.outputs.charm-paths != '[]' && needs.ci-ignore.outputs.any_modified == 'true' }}
strategy:
fail-fast: false
matrix:
charm-path: ${{ fromJSON(needs.resolve-charm-paths.outputs.charm-paths) }}
uses: canonical/observability/.github/workflows/_charm-quality-checks.yaml@v2
secrets: inherit
with:
charm-path: ${{ inputs.charm-path }}
charm-path: ${{ matrix.charm-path }}
provider: ${{ inputs.provider }}
charmcraft-channel: ${{ inputs.charmcraft-channel }}
juju-channel: ${{ inputs.juju-channel }}
parallelize-integration: ${{ inputs.parallelize-integration }}
automatically-retry-hooks: ${{ inputs.automatically-retry-hooks }}
enable-integration: ${{ inputs.enable-integration }}

38 changes: 29 additions & 9 deletions .github/workflows/charm-quality-gates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ on:
charm-path:
description: |
Path to the charm we want to promote. Defaults to the current working directory.
If 'charm-paths' is also provided, 'charm-paths' takes precedence and this input is ignored.
default: '.'
required: false
type: string
charm-paths:
description: |
JSON list of charm paths (e.g. '["charms/foo", "charms/bar"]').
If provided, takes precedence over 'charm-path'.
Each path will be processed as a separate matrix entry.
default: ''
required: false
type: string
tracks:
description: Json list of track names on which to run quality gates.
type: string
Expand All @@ -19,17 +28,25 @@ on:
required: true

concurrency:
group: quality-gates${{ (inputs.charm-path && inputs.charm-path != '.') && format('-{0}', inputs.charm-path) || '' }}
group: quality-gates-${{ github.ref }}${{ (inputs.charm-path && inputs.charm-path != '.') && format('-{0}', inputs.charm-path) || '' }}
cancel-in-progress: true

jobs:
resolve-charm-paths:
uses: canonical/observability/.github/workflows/_resolve-charm-paths.yaml@v1
with:
charm-path: ${{ inputs.charm-path }}
charm-paths: ${{ inputs.charm-paths }}
filter-by-changes: false

quality-gate-edge:
name: Quality gate (edge -> beta)
if: always()
name: Quality gate (edge -> beta) (${{ matrix.charm-path }})
needs: [resolve-charm-paths]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
charm-path: ${{ fromJSON(needs.resolve-charm-paths.outputs.charm-paths) }}
track: ${{ fromJSON(inputs.tracks) }}
steps:
- name: Checkout
Expand All @@ -41,18 +58,19 @@ jobs:
- name: Get charm name
id: get-charm-name
run: |
cd "${{ inputs.charm-path }}"
cd "${{ matrix.charm-path }}"
charm_name=$(yq .name metadata.yaml 2>/dev/null || yq .name charmcraft.yaml)
echo "charm_name=$charm_name"
echo "charm_name=$charm_name" >> "$GITHUB_OUTPUT"
- name: "Run the quality gates"
run: |
cd "${{ matrix.charm-path }}"
uvx tox -e qualitygate-beta
- name: Promote from edge to beta
env:
CHARMCRAFT_AUTH: ${{ secrets.CHARMHUB_TOKEN }}
CHARM_NAME: ${{ steps.get-charm-name.outputs.charm_name }}
CHARM_PATH: ${{ inputs.charm-path }}
CHARM_PATH: ${{ matrix.charm-path }}
TRACK: ${{ matrix.track }}
run: |
cd "$CHARM_PATH"
Expand All @@ -61,12 +79,13 @@ jobs:
echo "Promoted from edge to beta!"

quality-gate-beta:
name: Quality gate (beta -> candidate)
if: always()
name: Quality gate (beta -> candidate) (${{ matrix.charm-path }})
needs: [resolve-charm-paths]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
charm-path: ${{ fromJSON(needs.resolve-charm-paths.outputs.charm-paths) }}
track: ${{ fromJSON(inputs.tracks) }}
steps:
- name: Checkout
Expand All @@ -78,18 +97,19 @@ jobs:
- name: Get charm name
id: get-charm-name
run: |
cd "${{ inputs.charm-path }}"
cd "${{ matrix.charm-path }}"
charm_name=$(yq .name metadata.yaml 2>/dev/null || yq .name charmcraft.yaml)
echo "charm_name=$charm_name"
echo "charm_name=$charm_name" >> "$GITHUB_OUTPUT"
- name: "Run the quality gates"
run: |
cd "${{ matrix.charm-path }}"
uvx tox -e qualitygate-candidate
- name: Promote from beta to candidate
env:
CHARMCRAFT_AUTH: ${{ secrets.CHARMHUB_TOKEN }}
CHARM_NAME: ${{ steps.get-charm-name.outputs.charm_name }}
CHARM_PATH: ${{ inputs.charm-path }}
CHARM_PATH: ${{ matrix.charm-path }}
TRACK: ${{ matrix.track }}
run: |
cd "$CHARM_PATH"
Expand Down
Loading