diff --git a/.github/workflows/_charm-quality-checks.yaml b/.github/workflows/_charm-quality-checks.yaml
index 4042136..9e78037 100644
--- a/.github/workflows/_charm-quality-checks.yaml
+++ b/.github/workflows/_charm-quality-checks.yaml
@@ -56,12 +56,21 @@ jobs:
with:
fetch-depth: 1
- name: Check charm libraries # Make sure our charm libraries are updated
- uses: canonical/charming-actions/check-libraries@2.5.0-rc
- with:
- credentials: "${{ secrets.CHARMHUB_TOKEN }}"
- github-token: "${{ secrets.GITHUB_TOKEN }}"
+ env:
+ CHARMHUB_TOKEN: "${{ secrets.CHARMHUB_TOKEN }}"
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
charm-path: "${{ inputs.charm-path }}"
charmcraft-channel: "${{ inputs.charmcraft-channel }}"
+ run: |
+ pip install git+https://github.com/lucabello/noctua
+ outdated_libs=$(noctua charm libraries check --minor | jq 'length')
+ if [[ $outdated_libs != "0" ]]; then
+ gh pr edit ${{ github.event.number }} --remove-label="Libraries: OK"
+ gh pr edit ${{ github.event.number }} --add-label="Libraries: Out of sync"
+ else
+ gh pr edit ${{ github.event.number }} --remove-label="Libraries: Out of sync"
+ gh pr edit ${{ github.event.number }} --add-label="Libraries: OK"
+ fi
static-analysis:
name: Static Analysis
uses: canonical/observability/.github/workflows/_charm-static-analysis.yaml@main
diff --git a/.github/workflows/_charm-release.yaml b/.github/workflows/_charm-release.yaml
index 8e1bebf..3e47416 100644
--- a/.github/workflows/_charm-release.yaml
+++ b/.github/workflows/_charm-release.yaml
@@ -29,6 +29,12 @@ on:
required: false
description: |
The snap channel from which to install Charmcraft.
+ release-channel:
+ type: string
+ default: latest/edge
+ required: false
+ description: |
+ The default channel to release charms to.
secrets:
CHARMHUB_TOKEN:
required: true
@@ -136,27 +142,22 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 1
- - name: Select charmhub channel
- uses: canonical/charming-actions/channel@2.1.1
- id: channel
- name: Fetch charm artifacts
uses: actions/download-artifact@v3
with:
name: charms
path: "${{ github.workspace }}/${{ inputs.charm-path }}"
- - name: Upload charm to charmhub
- uses: canonical/charming-actions/upload-charm@2.5.0-rc
- with:
- credentials: "${{ secrets.CHARMHUB_TOKEN }}"
- github-token: "${{ secrets.GITHUB_TOKEN }}"
- channel: "${{ steps.channel.outputs.name }}"
- built-charm-path: "${{ matrix.path }}"
- charm-path: "${{ inputs.charm-path }}"
- tag-prefix: "${{ inputs.release-tag-prefix }}"
- charmcraft-channel: "${{ inputs.charmcraft-channel }}"
- # We set destructive mode to false, otherwise runner's OS would have to match
- # charm's 'build-on' OS.
- destructive-mode: false
+ - name: Upload charm to Charmhub
+ env:
+ CHARMHUB_TOKEN: ${{ secrets.CHARMHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ pip install git+https://github.com/lucabello/noctua
+ cd "${{ inputs.charm-path }}"
+ release=$(noctua charm release --path="${{ matrix.path }}" --channel=${{ inputs.release-channel }} --json | tail -n1)
+ revision=$(echo "$release" | jq .revision)
+ # TODO: push git tag; is it necessary?
+ gh release create "${{inputs.release-tag-prefix}}rev${revision}" --title="Revision ${revision}" --generate-notes
release-arm-to-charmhub:
name: Release arm64 to CharmHub
# needs to be run on arm or the oci image will resolve to the amd64 one.
@@ -172,31 +173,19 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 1
- - name: Select charmhub channel
- uses: canonical/charming-actions/channel@2.1.1
- id: channel
- name: Fetch charm artifacts
uses: actions/download-artifact@v3
with:
name: charms-arm
path: "${{ github.workspace }}/${{ inputs.charm-path }}"
- - name: Set up Docker
+ - name: Upload charm to Charmhub
+ env:
+ CHARMHUB_TOKEN: ${{ secrets.CHARMHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
- sudo snap install docker
- sudo addgroup --system docker
- sudo adduser $USER docker
- newgrp docker <<< "sudo snap disable docker"
- newgrp docker <<< "sudo snap enable docker"
- - name: Upload charm to charmhub
- uses: canonical/charming-actions/upload-charm@2.5.0-rc
- with:
- credentials: "${{ secrets.CHARMHUB_TOKEN }}"
- github-token: "${{ secrets.GITHUB_TOKEN }}"
- channel: "${{ steps.channel.outputs.name }}"
- built-charm-path: "${{ matrix.path }}"
- charm-path: "${{ inputs.charm-path }}"
- tag-prefix: "${{ inputs.release-tag-prefix }}"
- charmcraft-channel: "${{ inputs.charmcraft-channel }}"
- # We set destructive mode to false, otherwise runner's OS would have to match
- # charm's 'build-on' OS.
- destructive-mode: false
+ pip install git+https://github.com/lucabello/noctua
+ cd "${{ inputs.charm-path }}"
+ release=$(noctua charm release --path="${{ matrix.path }}" --channel=${{ inputs.release-channel }} --json | tail -n1)
+ revision=$(echo "$release" | jq .revision)
+ # TODO: push git tag; is it necessary?
+ gh release create "${{inputs.release-tag-prefix}}rev${revision}" --title="Revision ${revision}" --generate-notes
diff --git a/.github/workflows/_local-promote-train.yaml b/.github/workflows/_local-promote-train.yaml
index 8b40779..7d2d5ed 100644
--- a/.github/workflows/_local-promote-train.yaml
+++ b/.github/workflows/_local-promote-train.yaml
@@ -8,7 +8,11 @@ on:
type: boolean
default: false
required: true
-
+ track:
+ type: choice
+ description: Track on which to run the promotion train
+ options:
+ - latest
jobs:
promote:
name: Promote Charm
@@ -52,52 +56,7 @@ jobs:
echo "charm_path=$CHARM_PATH" >> $GITHUB_OUTPUT;
fi
- - name: Check which tracks already have a release
- id: check-tracks
- env:
- CHARMCRAFT_AUTH: ${{ secrets.CHARMHUB_TOKEN }}
- run: |
- sudo snap install charmcraft --classic
- cd ${{ steps.read-charm-path.outputs.charm_path }}
- charm_name=$(yq .name metadata.yaml 2>/dev/null || yq .name charmcraft.yaml)
- status=$(charmcraft status "$charm_name" --format=json)
- to_stable=$(echo "$status" | jq -r '.[] | select(.track == "latest") | .mappings[].releases[] | select(.channel == "latest/stable") | .status' | head -n1)
- to_candidate=$(echo "$status" | jq -r '.[] | select(.track == "latest") | .mappings[].releases[] | select(.channel == "latest/candidate") | .status' | head -n1)
- to_beta=$(echo "$status" | jq -r '.[] | select(.track == "latest") | .mappings[].releases[] | select(.channel == "latest/beta") | .status' | head -n1)
- echo "to_stable=$to_stable" >> $GITHUB_OUTPUT
- echo "to_candidate=$to_candidate" >> $GITHUB_OUTPUT
- echo "to_beta=$to_beta" >> $GITHUB_OUTPUT
-
- - name: (dry run) Print promotions
- if: ${{ inputs.dry-run }}
+ - name: Run the promotion train
run: |
- echo "${{ matrix.charm-repo }} would promote the following channels:"
- if [[ "${{ steps.check-tracks.outputs.to_stable }}" == "open" ]]; then echo "- latest/candidate --> latest/stable"; fi
- if [[ "${{ steps.check-tracks.outputs.to_candidate }}" == "open" ]]; then echo "- latest/beta --> latest/candidate"; fi
- if [[ "${{ steps.check-tracks.outputs.to_beta }}" == "open" ]]; then echo "- latest/edge --> latest/beta"; fi
-
- - name: Promote charm - latest/candidate --> latest/stable
- if: ${{ !inputs.dry-run && steps.check-tracks.outputs.to_stable == 'open' }}
- uses: canonical/charming-actions/promote-charm@2.6.0
- with:
- charm-path: ${{ steps.read-charm-path.outputs.charm_path }}
- credentials: ${{ secrets.CHARMHUB_TOKEN }}
- origin-channel: latest/candidate
- destination-channel: latest/stable
-
- - name: Promote charm - latest/beta --> latest/candidate
- if: ${{ !inputs.dry-run && steps.check-tracks.outputs.to_candidate == 'open' }}
- uses: canonical/charming-actions/promote-charm@2.6.0
- with:
- charm-path: ${{ steps.read-charm-path.outputs.charm_path }}
- credentials: ${{ secrets.CHARMHUB_TOKEN }}
- origin-channel: latest/beta
- destination-channel: latest/candidate
- - name: Promote charm - latest/edge --> latest/beta
- if: ${{ !inputs.dry-run && steps.check-tracks.outputs.to_beta == 'open' }}
- uses: canonical/charming-actions/promote-charm@2.6.0
- with:
- charm-path: ${{ steps.read-charm-path.outputs.charm_path }}
- credentials: ${{ secrets.CHARMHUB_TOKEN }}
- origin-channel: latest/edge
- destination-channel: latest/beta
+ pip install git+https://github.com/lucabello/noctua
+ noctua charm promote-train --track=${{ inputs.track }}
diff --git a/.github/workflows/charm-promote.yaml b/.github/workflows/charm-promote.yaml
index dcf59ee..ac45261 100644
--- a/.github/workflows/charm-promote.yaml
+++ b/.github/workflows/charm-promote.yaml
@@ -3,7 +3,7 @@ name: Promote Charm
on:
workflow_call:
inputs:
- charm-path:
+ charm-name:
description: "Path to the charm we want to promote. Defaults to the current working directory."
type: string
default: '.'
@@ -27,25 +27,23 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
+ - name: Setup Python
+ uses: actions/setup-python@v4
- name: Set target channel
env:
PROMOTE_FROM: ${{ github.event.inputs.promotion }}
run: |
if [ "${PROMOTE_FROM}" == "edge -> beta" ]; then
echo "promote-from=edge" >> ${GITHUB_ENV}
- echo "promote-to=beta" >> ${GITHUB_ENV}
elif [ "${PROMOTE_FROM}" == "beta -> candidate" ]; then
echo "promote-from=beta" >> ${GITHUB_ENV}
- echo "promote-to=candidate" >> ${GITHUB_ENV}
elif [ "${PROMOTE_FROM}" == "candidate -> stable" ]; then
echo "promote-from=candidate" >> ${GITHUB_ENV}
- echo "promote-to=stable" >> ${GITHUB_ENV}
fi
- name: Promote Charm
- uses: canonical/charming-actions/promote-charm@2.6.0
- with:
- charm-path: ${{ inputs.charm-path }}
- credentials: ${{ secrets.CHARMHUB_TOKEN }}
- destination-channel: ${{ github.event.inputs.track }}/${{ env.promote-to }}
- origin-channel: ${{ github.event.inputs.track }}/${{ env.promote-from }}
- charmcraft-channel: latest/stable
+ env:
+ CHARMHUB_TOKEN: ${{ secrets.CHARMHUB_TOKEN }}
+ run: |
+ pip install git+https://github.com/lucabello/noctua
+ cd ${{ inputs.charm-path }}
+ noctua charm promote --from=${{ github.event.inputs.track }}/${{ env.promote-from }}
diff --git a/.github/workflows/charm-update-libs.yaml b/.github/workflows/charm-update-libs.yaml
index 9b80aa9..a54ec95 100644
--- a/.github/workflows/charm-update-libs.yaml
+++ b/.github/workflows/charm-update-libs.yaml
@@ -63,26 +63,9 @@ jobs:
- name: Check for major library updates
run: |
sudo snap install charmcraft --classic --channel "${{ inputs.charmcraft-channel }}"
+ pip install git+https://github.com/lucabello/noctua
cd "$GITHUB_WORKSPACE/${{ inputs.charm-path }}"
- # Get the charm name
- charm_name=$((yq .name metadata.yaml 2>/dev/null || yq .name charmcraft.yaml) | tr - _)
- if [[ $charm_name = "" ]]; then echo "Error: can't extract the charm name." && exit 1; fi
- # Initalize the issue body content to empty string, and fill it up in the for loop
- issue_body=""
- # For each library not belonging to the charm, check for a major version update
- # "lib" would be of the form `charms.prometheus_k8s.v0.prometheus_scrape`
- for lib in $(find "lib/charms/" -type f -name "*.py" | grep -v "$charm_name" | sed 's|lib/||' | sed 's/.py//' | sed 's|/|.|g'); do
- # Extract the name of the library, the current major version, and the charm that owns it
- lib_name=$(cut -d. -f4 <<< "$lib")
- lib_major=$(cut -d. -f3 <<< "$lib")
- lib_owner=$(cut -d. -f2 <<< "$lib" | tr _ -)
- # Get the latest major version of the library from Charmhub
- latest_major="v$(charmcraft list-lib $lib_owner --format=json | jq -r --arg LIBNAME $lib_name '.[] | select(.library_name == $LIBNAME) | .api')"
- # If there is a new major version of the library, open a new issue
- if [[ $(printf "%s\n%s" "$lib_major" "$latest_major" | sort -V | tail -n1 ) != "$lib_major" ]]; then
- issue_body=$(printf "%s\n%s" "$issue_body" "- update $lib to $latest_major")
- fi
- done
+ issue_body=$(noctua charm libraries check --major)
# Check if there are already open issues for major library upgrades
open_issues_count="$(gh issue list --search 'chore: update libraries to new major versions' --state open --json id --jq 'length')"
# Complete $issue_body if it's not empty
@@ -109,7 +92,7 @@ jobs:
cd "$GITHUB_WORKSPACE"
env:
CHARMCRAFT_AUTH: "${{ secrets.CHARMHUB_TOKEN }}"
- GH_TOKEN: "${{ secrets.OBSERVABILITY_NOCTUA_TOKEN }}"
+ GITHUB_TOKEN: "${{ secrets.OBSERVABILITY_NOCTUA_TOKEN }}"
- name: Fetch charm libraries
run: |
diff --git a/.github/workflows/rock-release-oci-factory.yaml b/.github/workflows/rock-release-oci-factory.yaml
index be80643..716a8d5 100644
--- a/.github/workflows/rock-release-oci-factory.yaml
+++ b/.github/workflows/rock-release-oci-factory.yaml
@@ -69,49 +69,13 @@ jobs:
id: update-releases
if: steps.changed-files.outputs.all_changed_and_modified_files != ''
run: |
- # Get the tags already in OCI Factory
- existing_tags="$(jq -r 'to_entries[] | .key' $GITHUB_WORKSPACE/oci-factory/oci/${{ inputs.rock-name }}/_releases.json | sed 's/-22.04//')"
- # Get the versions from the rocks that have been modified
- modified_tags="$(echo ${{ steps.changed-files.outputs.all_changed_and_modified_files }} | tr ' ' '\n' | sed s@/rockcraft.yaml@@)"
- # Merge the two to make a list of all the versions that will be in OCI Factory with
- # the PR that is being opened in this workflow
- all_tags="$existing_tags\n$modified_tags"
- today="$(date)"
- echo "now_epoch=$(date -d now +%s)" >> $GITHUB_OUTPUT # to create a unique branch name on the fork
- end_of_life="$(date -d "$today+3 months" +%Y-%m-%d)"
- yq -i ".upload = []" $GITHUB_WORKSPACE/oci-factory/oci/${{ inputs.rock-name }}/image.yaml
- for file in ${{ steps.changed-files.outputs.all_changed_and_modified_files }}; do
- # For each rock version, build the `upload:` element for image.yaml as a json
- # Example: {"source": "canonical/prometheus-rock", "commit": "...", ...}
- patch_tag=""; minor_tag=""; major_tag=""
- tag_json_format='"%s-22.04": {"end-of-life": "%sT00:00:00Z", "risks":["stable"]}'
- # Parse the rock version from the rockcraft.yaml
- rock_version=$(yq -r '.version' $GITHUB_WORKSPACE/rock/$file)
- # Always tag with patch
- patch_tag=$(printf "$tag_json_format" "$rock_version" "$end_of_life")
- # If rock_version is the latest tag among the ones with equal major.minor, apply major.minor
- rock_major_minor=$(echo $rock_version | sed -E "s/([0-9]+\.[0-9]+).*/\1/")
- same_major_minor=$(printf "%s\n%s" "$all_tags" "$rock_version" | grep "$rock_major_minor")
- if [[ $(echo "$same_major_minor" | sort -V | tail -n1) == "$rock_version" ]]; then
- minor_tag=$(printf ",$tag_json_format" "$rock_major_minor" "$end_of_life")
- fi
- # If rock_version is the latest among the ones with equal major, apply major
- rock_major=$(echo $rock_version | sed -E "s/([0-9]+).*/\1/")
- same_major=$(printf "%s\n%s" "$all_tags" "$rock_version" | grep "$rock_major")
- if [[ $(echo "$same_major" | sort -V | tail -n1) == "$rock_version" ]]; then
- major_tag=$(printf ",$tag_json_format" "$rock_major" "$end_of_life")
- fi
- # Build the final JSON object to update image.yaml
- rock_tags=$(printf '{%s%s%s}' "$patch_tag" "$minor_tag" "$major_tag")
- upload_item_format='{"source":"%s","commit":"%s","directory":"%s","release":%s}'
- upload_item=$(printf "$upload_item_format" \
- "canonical/${{ inputs.rock-name }}-rock" \
- "${{ steps.commit-sha.outputs.commit_sha }}" \
- "$rock_version" \
- "$rock_tags" \
- )
- yq -i ".upload += $upload_item" $GITHUB_WORKSPACE/oci-factory/oci/${{ inputs.rock-name }}/image.yaml
- done
+ pip install git+https://github.com/lucabello/noctua
+ versions="$(echo ${{ steps.changed-files.outputs.all_changed_and_modified_files }} | tr ' ' '\n' | grep rockcraft.yaml | sed 's@/rockcraft.yaml@@g')"
+ noctua rock manifest "${{ github.repository }}" \
+ --commit="${{ steps.commit-sha.outputs.commit_sha }}" \
+ --base=22.04 \
+ $(echo $versions | sed -E 's/(\S+)/--version \1/g' | tr '\n' ' ') \ # build the --version flags
+ > $GITHUB_WORKSPACE/oci-factory/oci/${{ inputs.rock-name }}/image.yaml
- name: Commit to the fork
id: fork-commit