Skip to content
Closed
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
91 changes: 85 additions & 6 deletions .github/workflows/rock-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ name: Pull Request

on:
workflow_call:
inputs:
rock-path:
description: "Path to the rock root"
required: false
default: "."
type: string


jobs:
Expand All @@ -10,23 +16,84 @@ jobs:
runs-on: ubuntu-24.04
outputs:
versions: ${{ steps.changed-versions.outputs.versions }}
is_monorepo: ${{ steps.detect-layout.outputs.is_monorepo }}
rock_path: ${{ steps.detect-layout.outputs.rock_path }}
just_dir: ${{ steps.detect-layout.outputs.just_dir }}
rock_name: ${{ steps.detect-layout.outputs.rock_name }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Detect rock layout
id: detect-layout
env:
ROCK_PATH_INPUT: ${{ inputs.rock-path }}
run: |
# Normalize the configured rock path.
rock_path="${ROCK_PATH_INPUT:-.}"
rock_path="${rock_path%/}"
if [[ "$rock_path" == "" ]]; then
rock_path="."
fi

# If rock-path has a justfile, it's a single-rock repo.
# Otherwise treat it as a rock folder inside a monorepo and run just one level up.
if [[ -f "$rock_path/justfile" ]]; then
is_monorepo="false"
just_dir="$rock_path"
rock_name=""
else
is_monorepo="true"
just_dir="$(dirname "$rock_path")"
rock_name="$(basename "$rock_path")"
fi

{
echo "rock_path=$rock_path"
echo "just_dir=$just_dir"
echo "rock_name=$rock_name"
echo "is_monorepo=$is_monorepo"
} >> "$GITHUB_OUTPUT"
- name: Find rockcraft.yaml changes
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: "**/rockcraft.yaml"
files: "${{ steps.detect-layout.outputs.rock_path }}/**/rockcraft.yaml"
- name: Extract the versions
id: changed-versions
env:
# CHANGED_FILES is a space-separated list
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
IS_MONOREPO: ${{ steps.detect-layout.outputs.is_monorepo }}
ROCK_PATH: ${{ steps.detect-layout.outputs.rock_path }}
ROCK_NAME: ${{ steps.detect-layout.outputs.rock_name }}
run: |
versions="${CHANGED_FILES//\/rockcraft.yaml/}" # space-separated versions
versions=""
path_prefix=""
if [[ "$ROCK_PATH" != "." ]]; then
path_prefix="$ROCK_PATH/"
fi
# Convert changed rockcraft.yaml files into version tokens.
for file in $CHANGED_FILES; do
if [[ -n "$path_prefix" && "$file" != "$path_prefix"* ]]; then
continue
fi
relative="$file"
if [[ -n "$path_prefix" ]]; then
relative="${file#"$path_prefix"}"
fi
if [[ "$IS_MONOREPO" == "true" ]]; then
version="${relative%%/*}"
versions="$versions $version"
else
version="${relative%%/*}"
versions="$versions $version"
fi
done
versions="${versions# }"
echo "versions=$versions"
echo "versions=$versions" >> "$GITHUB_OUTPUT"
{
echo "versions=$versions"
} >> "$GITHUB_OUTPUT"

tests:
name: Tests
Expand Down Expand Up @@ -63,10 +130,22 @@ jobs:
run: df -h
- name: Pack and test the rocks
run: |
rock_path="${{ needs.changes.outputs.just_dir }}"
is_monorepo="${{ needs.changes.outputs.is_monorepo }}"
rock_name="${{ needs.changes.outputs.rock_name }}"
cd "$rock_path"
for version in ${{ needs.changes.outputs.versions }}; do
just pack "$version"
just test "$version"
just clean "$version"
if [[ "$is_monorepo" == "true" ]]; then
# Monorepo: pass rock name and version.
just pack "$rock_name" "$version"
just test "$rock_name" "$version"
just clean "$rock_name" "$version"
else
# Single rock: pass version only.
just pack "$version"
just test "$version"
just clean "$version"
fi
done
- name: Print disk utilization after packing
if: ${{ (runner.debug == '1') }}
Expand Down
70 changes: 62 additions & 8 deletions .github/workflows/rock-release-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
description: "Name of the application for which to build the rock"
required: true
type: string
rock-path:
description: "Path to the rock root"
required: false
default: "."
type: string
secrets:
OBSERVABILITY_NOCTUA_TOKEN:
required: true
Expand All @@ -24,36 +29,85 @@ jobs:
# Install Syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
| sh -s -- -b /usr/local/bin
- name: Resolve rock context
id: rock-context
env:
ROCK_PATH_INPUT: ${{ inputs.rock-path }}
run: |
# Normalize the configured rock path.
rock_path="${ROCK_PATH_INPUT:-.}"
rock_path="${rock_path%/}"
if [[ "$rock_path" == "" ]]; then
rock_path="."
fi

# Detect mode from the presence of a justfile in the provided rock path.
if [[ -f "$rock_path/justfile" ]]; then
is_monorepo="false"
just_dir="$rock_path"
rock_dir="$rock_path"
just_rock_name=""
else
is_monorepo="true"
rock_dir="$rock_path"
just_dir="$(dirname "$rock_path")"
just_rock_name="$(basename "$rock_path")"
fi

# Resolve the latest version directory under the selected rock path.
latest_version="$(find "$rock_dir" -maxdepth 1 -type d -name '[0-9]*' | sort -V | tail -n1 | sed 's@.*/@@')"
if [[ -z "$latest_version" ]]; then
echo "No version directories found under $rock_dir" >&2
exit 1
fi
version_dir="$rock_dir/$latest_version"
# Export derived paths and mode for downstream steps.
{
echo "rock_path=$rock_path"
echo "just_dir=$just_dir"
echo "just_rock_name=$just_rock_name"
echo "rock_dir=$rock_dir"
echo "latest_version=$latest_version"
echo "version_dir=$version_dir"
echo "is_monorepo=$is_monorepo"
} >> "$GITHUB_OUTPUT"
- name: Build rock
working-directory: ${{ steps.rock-context.outputs.just_dir }}
env:
JUST_ROCK_NAME: ${{ steps.rock-context.outputs.just_rock_name }}
IS_MONOREPO: ${{ steps.rock-context.outputs.is_monorepo }}
LATEST_VERSION: ${{ steps.rock-context.outputs.latest_version }}
run: |
latest_version="$(find . -maxdepth 1 -type d -name '[0-9]*' | sort -V | tail -n1 | sed 's@./@@')"
just pack "$latest_version"
# Use rock-name + version for monorepos, otherwise version-only.
if [[ "$IS_MONOREPO" == "true" ]]; then
just pack "$JUST_ROCK_NAME" "$LATEST_VERSION"
else
just pack "$LATEST_VERSION"
fi
- name: Upload rock to ghcr.io
working-directory: ${{ steps.rock-context.outputs.version_dir }}
env:
ROCK_NAME: ${{ inputs.rock-name }}
OBSERVABILITY_NOCTUA_TOKEN: ${{ secrets.OBSERVABILITY_NOCTUA_TOKEN }}
run: |
latest_version="$(find . -maxdepth 1 -type d -name '[0-9]*' | sort -V | tail -n1 | sed 's@./@@')"
cd "$latest_version"
sudo skopeo --insecure-policy copy \
"oci-archive:$(realpath ./*.rock)" \
"docker://ghcr.io/canonical/$ROCK_NAME:dev" \
--dest-creds "observability-noctua-bot:$OBSERVABILITY_NOCTUA_TOKEN"
- name: Create SBOM
working-directory: ${{ steps.rock-context.outputs.version_dir }}
env:
ROCK_NAME: ${{ inputs.rock-name }}
run: |
latest_version="$(find . -maxdepth 1 -type d -name '[0-9]*' | sort -V | tail -n1 | sed 's@./@@')"
cd "$latest_version"
# shellcheck disable=SC2086 # glob passed to realpath can't be wrapped
syft "$(realpath ./${ROCK_NAME}_*.rock)" -o "spdx-json=${ROCK_NAME}.sbom.json"
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.rock-name }}-sbom
path: "${{ inputs.rock-name}}.sbom.json"
path: "${{ steps.rock-context.outputs.version_dir }}/${{ inputs.rock-name}}.sbom.json"
- name: Upload locally built rock artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.rock-name }}-rock
path: "${{ inputs.rock-name }}_*.rock"
path: "${{ steps.rock-context.outputs.version_dir }}/${{ inputs.rock-name }}_*.rock"
60 changes: 55 additions & 5 deletions .github/workflows/rock-release-oci-factory.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ on:
description: "Name of the application for which to build the rock"
required: true
type: string
rock-path:
description: "Path to the rock root"
required: false
default: "."
type: string
risk-track:
description: "Risk track on which to release the rock"
required: false
Expand Down Expand Up @@ -39,7 +44,7 @@ jobs:
uses: tj-actions/changed-files@v46
with:
path: rock
files: '**/rockcraft.yaml'
files: '${{ inputs.rock-path }}/**/rockcraft.yaml'
- name: Sync the OCI Factory fork
id: fork-sync
if: steps.changed-files.outputs.all_changed_and_modified_files != ''
Expand All @@ -64,16 +69,61 @@ jobs:
shell: bash # The for-loop parsing is bash-specific
env:
ROCK_NAME: ${{ inputs.rock-name }}
ROCK_PATH_INPUT: ${{ inputs.rock-path }}
# CHANGED_FILES is a space-separated list
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_and_modified_files }}
RISK_TRACK: ${{ inputs.risk-track }}
run: |
TRACK=${RISK_TRACK:-stable}
cd rock
# Normalize the configured rock path.
rock_path="${ROCK_PATH_INPUT:-.}"
rock_path="${rock_path%/}"
if [[ "$rock_path" == "" ]]; then
rock_path="."
fi

# If rock-path has a justfile, it's a single-rock repo.
# Otherwise treat it as a rock folder inside a monorepo.
if [[ -f "rock/$rock_path/justfile" ]]; then
is_monorepo="false"
else
is_monorepo="true"
fi

# All version folders are located under rock_path in both modes.
cd "rock/$rock_path"
# Export current time to create a unique branch name for the fork
echo "now_epoch=$(date -d now +%s)" >> "$GITHUB_OUTPUT"
sha="$(git rev-parse HEAD)"
versions="${CHANGED_FILES//\/rockcraft.yaml/}" # space-separated versions
versions=""
path_prefix=""
if [[ "$rock_path" != "." ]]; then
path_prefix="$rock_path/"
fi
# Extract version numbers from changed rockcraft.yaml files.
for file in $CHANGED_FILES; do
if [[ -n "$path_prefix" && "$file" != "$path_prefix"* ]]; then
continue
fi
relative="$file"
if [[ -n "$path_prefix" ]]; then
relative="${file#"$path_prefix"}"
fi
if [[ "$is_monorepo" == "true" ]]; then
version="${relative%%/*}"
versions="$versions $version"
else
version="${relative%%/*}"
versions="$versions $version"
fi
done
versions="${versions# }"
if [[ -z "$versions" ]]; then
echo "No changed rockcraft.yaml files for $ROCK_NAME" >&2
echo "has_versions=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "has_versions=true" >> "$GITHUB_OUTPUT"
# Build the --version flags for noctua
versions_flags="$(for v in $versions; do echo -n "--version=$v "; done)"
# Generate the manifest via noctua
Expand All @@ -87,7 +137,7 @@ jobs:
> "$GITHUB_WORKSPACE/oci-factory/oci/$ROCK_NAME/image.yaml"
- name: Commit to the fork
id: fork-commit
if: steps.changed-files.outputs.all_changed_and_modified_files != ''
if: steps.update-releases.outputs.has_versions == 'true'
uses: EndBug/add-and-commit@v9
with:
add: 'oci/${{ inputs.rock-name }}/image.yaml'
Expand All @@ -96,7 +146,7 @@ jobs:
new_branch: 'update-${{ steps.update-releases.outputs.now_epoch }}'
push: 'origin update-${{ steps.update-releases.outputs.now_epoch }} --force'
- name: Open a PR from the fork to upstream
if: steps.changed-files.outputs.all_changed_and_modified_files != ''
if: steps.update-releases.outputs.has_versions == 'true'
id: upstream-pr
env:
GH_TOKEN: "${{ secrets.OBSERVABILITY_NOCTUA_TOKEN }}"
Expand Down
Loading