fix: use python 3.13 to build 26.04 and fix post deply checks #301
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" | |
| # We don't run this workflow on 'pull_request', because we require secrets to | |
| # upload the charm to Charmhub, and pull_request runs can't access secrets. | |
| # PRs should be opened from a branch on the main juju/juju-controller repo, | |
| # not from a fork. | |
| on: | |
| push: | |
| workflow_dispatch: | |
| env: | |
| CHARM_NAME: ${{ vars.CHARM_NAME }} | |
| jobs: | |
| unit-tests: | |
| name: Unit tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.10' | |
| - name: Install uv | |
| run: pip install uv | |
| - name: Create uv virtualenv | |
| run: uv venv | |
| - name: Install dependencies for testing | |
| run: | | |
| source .venv/bin/activate | |
| uv pip install ".[dev]" | |
| - name: Run tests | |
| run: | | |
| source .venv/bin/activate | |
| ./run_tests | |
| build: | |
| name: Build charm (${{ matrix.platform }}) | |
| needs: unit-tests | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: ubuntu@20.04:amd64 | |
| uv_python: "3.8" | |
| artifact_name: charm-ubuntu-20.04-amd64 | |
| - platform: ubuntu@22.04:amd64 | |
| uv_python: "3.10" | |
| artifact_name: charm-ubuntu-22.04-amd64 | |
| - platform: ubuntu@24.04:amd64 | |
| uv_python: "3.12" | |
| artifact_name: charm-ubuntu-24.04-amd64 | |
| - platform: ubuntu@26.04:amd64 | |
| uv_python: "3.13" | |
| artifact_name: charm-ubuntu-26.04-amd64 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.uv_python }} | |
| - name: Install uv | |
| run: pip install uv | |
| - name: Set up LXD | |
| uses: canonical/setup-lxd@90d76101915da56a42a562ba766b1a77019242fd | |
| - name: Add runner to lxd group | |
| run: | | |
| sudo usermod -a -G lxd $USER | |
| newgrp lxd | |
| - name: Install charmcraft | |
| # We use latest because there's no 4.x track yet. | |
| run: sudo snap install charmcraft --classic --channel=latest/stable | |
| - name: Pack charm | |
| run: sg lxd -c "UV_PYTHON=${{ matrix.uv_python }} charmcraft pack --platform='${{ matrix.platform }}'" | |
| - name: Upload charm artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact_name }} | |
| path: "*.charm" | |
| channel: | |
| name: Select Charmhub channel | |
| runs-on: ubuntu-latest | |
| outputs: | |
| test: ${{ steps.channel.outputs.test }} | |
| release: ${{ steps.channel.outputs.release }} | |
| steps: | |
| - name: Select Charmhub channel | |
| id: channel | |
| shell: bash | |
| run: | | |
| set -eux | |
| case ${{ github.ref_name }} in | |
| 3.* | 4.*) | |
| TRACK=$(echo "${{ github.ref_name }}" | awk -F "-" '{print $1}') | |
| DO_RELEASE=true | |
| ;; | |
| main) | |
| TRACK="latest" | |
| DO_RELEASE=true | |
| ;; | |
| *) | |
| TRACK="latest" | |
| DO_RELEASE=false # Don't release feature branches | |
| ;; | |
| esac | |
| # Feature branches will be released to the 'latest' track, so we need | |
| # to include the branch name to disambiguate. | |
| BRANCH="${{ github.ref_name }}-${{ github.sha }}" | |
| echo "test=$TRACK/edge/$BRANCH" >> "$GITHUB_OUTPUT" | |
| if [[ "$DO_RELEASE" == 'true' ]]; then | |
| echo "release=$TRACK/edge" >> "$GITHUB_OUTPUT" | |
| fi | |
| upload: | |
| name: Upload to Charmhub | |
| needs: [build, channel] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Download packed charm | |
| id: download | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: charm-ubuntu-* | |
| merge-multiple: true | |
| path: charms | |
| - name: Upload charms to Charmhub | |
| env: | |
| CHARMCRAFT_AUTH: ${{ secrets.CHARMCRAFT_AUTH }} | |
| run: | | |
| # We use latest because there's no 4.x track yet. | |
| sudo snap install charmcraft --channel latest/stable --classic | |
| for FILE in charms/*.charm; do | |
| echo "Uploading: $FILE" | |
| charmcraft upload --name "$CHARM_NAME" --release "${{ needs.channel.outputs.test }}" "$FILE" | |
| done | |
| integration: | |
| name: "Integration tests" | |
| runs-on: ubuntu-latest | |
| needs: [build, upload, channel] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| cloud: ["lxd", "microk8s"] | |
| steps: | |
| - name: Save charmcraft logs as artifact | |
| if: always() && steps.charmcraft.outcome != 'skipped' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: charmcraft-upload-logs | |
| path: ~/.local/state/charmcraft/log/ | |
| continue-on-error: true | |
| - name: Setup LXD | |
| if: matrix.cloud == 'lxd' | |
| uses: canonical/setup-lxd@2fa6235ef2dfd3288e0de09edac03f2ebf922968 | |
| - name: Set up MicroK8s | |
| if: matrix.cloud == 'microk8s' | |
| uses: balchua/microk8s-actions@v0.4.2 | |
| with: | |
| channel: "1.36-strict/stable" | |
| addons: '["dns", "hostpath-storage"]' | |
| - name: Install Juju | |
| run: | | |
| sudo snap install juju --channel 3/stable | |
| - name: Bootstrap on LXD | |
| if: matrix.cloud == 'lxd' | |
| run: | | |
| juju bootstrap lxd c \ | |
| --controller-charm-channel=${{ needs.channel.outputs.test }} | |
| - name: Bootstrap on MicroK8s | |
| if: matrix.cloud == 'microk8s' | |
| run: | | |
| sg snap_microk8s <<EOF | |
| juju bootstrap microk8s c \ | |
| --controller-charm-channel=${{ needs.channel.outputs.test }} | |
| EOF | |
| - name: Check charm status | |
| run: | | |
| juju switch controller | |
| juju status | |
| start_time="$(date -u +%s)" | |
| timeout=600 | |
| while true; do | |
| status_json="$(juju status --format=json 2>/dev/null || echo '{}')" | |
| app_status="$( | |
| jq -r \ | |
| '.applications.controller["application-status"].current // "unknown"' \ | |
| <<<"${status_json}" | |
| )" | |
| if jq -e ' | |
| (.applications.controller.units // {}) | |
| | to_entries | |
| | any( | |
| .[]; | |
| .value["workload-status"].current == "error" | |
| or .value["juju-status"].current == "error" | |
| ) | |
| ' >/dev/null <<<"${status_json}"; then | |
| echo "Controller unit entered error state" | |
| juju status | |
| exit 1 | |
| fi | |
| if [[ "${app_status}" == "active" ]] && jq -e ' | |
| (.applications.controller.units // {}) | |
| | to_entries | |
| | length > 0 | |
| and all( | |
| .[]; | |
| .value["workload-status"].current == "active" | |
| and .value["juju-status"].current == "idle" | |
| ) | |
| ' >/dev/null <<<"${status_json}"; then | |
| break | |
| fi | |
| echo "Waiting for controller to become ready..." | |
| juju status | |
| sleep 10 | |
| elapsed=$(( $(date -u +%s) - start_time )) | |
| if [[ ${elapsed} -ge ${timeout} ]]; then | |
| echo "Timed out waiting for controller to become ready" | |
| juju status | |
| exit 1 | |
| fi | |
| done | |
| - name: Get some info for debugging | |
| if: failure() | |
| run: | | |
| set -x | |
| set +e | |
| juju status -m controller | |
| juju debug-log -m controller --replay | |
| sg snap_microk8s <<EOF | |
| microk8s.kubectl -n controller-c get all | |
| microk8s.kubectl -n controller-c get -o yaml pod/controller-0 | |
| EOF | |
| # TODO: test integration with dashboard / ha-proxy |