Skip to content
Draft
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
3 changes: 3 additions & 0 deletions charmcraft/application/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
docs_url="https://documentation.ubuntu.com/charmcraft/{version}",
supports_multi_base=True,
mandatory_adoptable_fields=[], # Version field is not mandatory.
use_git_build_root=util.strtobool(
os.getenv(const.EXPERIMENTAL_MONOREPO_ENV_VAR, "false")
),
)

PRIME_BEHAVIOUR_CHANGE_MESSAGE = (
Expand Down
1 change: 1 addition & 0 deletions charmcraft/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
ALTERNATE_AUTH_ENV_VAR = "CHARMCRAFT_AUTH"
DEVELOPER_MODE_ENV_VAR = "CHARMCRAFT_DEVELOPER"
EXPERIMENTAL_EXTENSIONS_ENV_VAR = "CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS"
EXPERIMENTAL_MONOREPO_ENV_VAR = "CHARMCRAFT_EXPERIMENTAL_MONOREPO"
IMAGE_INFO_ENV_VAR = "CHARMCRAFT_IMAGE_INFO"
PROVIDER_ENV_VAR = "CHARMCRAFT_PROVIDER"
SHARED_CACHE_ENV_VAR = "CRAFT_SHARED_CACHE"
Expand Down
2 changes: 1 addition & 1 deletion charmcraft/parts/plugins/_poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def _get_package_install_commands(self) -> list[str]:
return [
*super()._get_package_install_commands(),
*utils.get_charm_copy_commands(
self._part_info.part_build_dir, self._part_info.part_install_dir
self._part_info.part_build_subdir, self._part_info.part_install_dir
),
]

Expand Down
2 changes: 1 addition & 1 deletion charmcraft/parts/plugins/_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def _get_package_install_commands(self) -> list[str]:
f"{pip} install --no-deps {install_params}",
f"{pip} check",
*utils.get_charm_copy_commands(
self._part_info.part_build_dir, self._part_info.part_install_dir
self._part_info.part_build_subdir, self._part_info.part_install_dir
),
]

Expand Down
2 changes: 1 addition & 1 deletion charmcraft/parts/plugins/_uv.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _get_package_install_commands(self) -> list[str]:
return [
*orig_cmds,
*utils.get_charm_copy_commands(
self._part_info.part_build_dir, self._part_info.part_install_dir
self._part_info.part_build_subdir, self._part_info.part_install_dir
),
]

Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,13 @@ url = "https://people.canonical.com/~lengau/python-apt-ubuntu-wheels/"
explicit = true

[tool.uv.sources]
craft-application = { git = "https://github.com/canonical/craft-application.git", branch = "work/CHARMCRAFT-710-prototype-e2e" }
craft-cli = { git = "https://github.com/canonical/craft-cli.git", branch = "main" }
craft-grammar = { git = "https://github.com/canonical/craft-grammar.git", branch = "main" }
craft-parts = { git = "https://github.com/canonical/craft-parts.git", branch = "work/CHARMCRAFT-710-prototype-e2e" }
craft-providers = { git = "https://github.com/canonical/craft-providers.git", branch = "main" }
craft-platforms = { git = "https://github.com/canonical/craft-platforms.git", branch = "main" }
craft-store = { git = "https://github.com/canonical/craft-store.git", branch = "main" }
Comment on lines 507 to +514
python-apt = { index = "python-apt-wheels" }

[tool.ty.src]
Expand Down
9 changes: 0 additions & 9 deletions spread.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,8 @@ suites:
summary: real charm building tests
prepare: |
snap install juju --channel=3/stable
snap install microk8s --channel=1.28-strict/stable
# Set up Juju controllers for the charms
lxc network set lxdbr0 ipv6.address none
mkdir -p ~/.local/share # Workaround for Juju not being able to create the directory
microk8s enable hostpath-storage
microk8s enable dns
snap alias microk8s.kubectl kubectl

if ! juju controllers | grep -q k8s; then
juju bootstrap microk8s k8s
fi
if ! juju controllers | grep -q lxd; then
juju bootstrap localhost lxd
fi
Expand Down
9 changes: 9 additions & 0 deletions tests/spread/charms/k8s-operator/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ environment:
JUJU_MODEL: k8s-operator-test

prepare: |
snap install microk8s --channel=1.28-strict/stable
microk8s status --wait-ready
microk8s enable hostpath-storage
microk8s enable dns
snap alias microk8s.kubectl kubectl
if ! juju controllers | grep -q k8s; then
juju bootstrap microk8s k8s
fi

git clone --depth=1 "${CHARM}" charm

restore: |
Expand Down
40 changes: 40 additions & 0 deletions tests/spread/charms/monorepo/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
summary: Pack a charm from a monorepo using CHARMCRAFT_EXPERIMENTAL_MONOREPO

systems:
- ubuntu-26.04-64

kill-timeout: 60m

environment:
CHARMCRAFT_EXPERIMENTAL_MONOREPO: "1"
REPO/mysql_operators_machines: mysql-operators
CHARM_SUBDIR/mysql_operators_machines: machines
REPO/mysql_operators_kubernetes: mysql-operators
CHARM_SUBDIR/mysql_operators_kubernetes: kubernetes
REPO/mysql_router_operators_machines: mysql-router-operators
CHARM_SUBDIR/mysql_router_operators_machines: machines
REPO/mysql_router_operators_kubernetes: mysql-router-operators
CHARM_SUBDIR/mysql_router_operators_kubernetes: kubernetes

prepare: |
apt-get install -y python3-yaml
git clone --depth=1 https://github.com/canonical/"${REPO}".git /tmp/"${REPO}"
python3 - << 'EOF'
import os, yaml, pathlib
Comment on lines +21 to +23
p = pathlib.Path(f'/tmp/{os.environ["REPO"]}/{os.environ["CHARM_SUBDIR"]}/charmcraft.yaml')
d = yaml.safe_load(p.read_text())
d["parts"].pop("files", None)
d["parts"].get("charm-poetry", {}).pop("override-build", None)
p.write_text(yaml.safe_dump(d))
EOF

restore: |
cd /tmp/"${REPO}"/"${CHARM_SUBDIR}" 2>/dev/null && charmcraft clean || true
rm -rf /tmp/"${REPO}"

execute: |
cd /tmp/"${REPO}"/"${CHARM_SUBDIR}"
charmcraft pack
CHARM_FILE=$(ls *_ubuntu@26.04-amd64.charm | head -1)
unzip -l "${CHARM_FILE}" | MATCH "src/charm.py"
unzip -l "${CHARM_FILE}" | MATCH "venv/lib/python.*/site-packages/ops/"
62 changes: 62 additions & 0 deletions tests/spread/commands/git-build-root/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
summary: Pack a charm from a monorepo using CHARMCRAFT_EXPERIMENTAL_MONOREPO

# Ubuntu 18.04 times out during global prepare (snap installs too slow).
systems:
- ubuntu-20.04-64
- ubuntu-22.04-64
- ubuntu-24.04-64
- ubuntu-25.10-64
- ubuntu-26.04-64

kill-timeout: 30m

environment:
CHARMCRAFT_EXPERIMENTAL_MONOREPO: "1"

execute: |
. /etc/os-release

mkdir -p /tmp/monorepo/shared/mylib
mkdir -p /tmp/monorepo/charm
git -C /tmp/monorepo init
git -C /tmp/monorepo config user.email "test@example.com"
git -C /tmp/monorepo config user.name "Test"

echo "GREETING = 'hello from shared library'" > /tmp/monorepo/shared/mylib/__init__.py

cat > /tmp/monorepo/charm/charmcraft.yaml << EOF
name: monorepo-test-charm
type: charm
title: Monorepo test charm
summary: Tests git-driven build root monorepo support.
description: Verifies that CHARMCRAFT_EXPERIMENTAL_MONOREPO mounts the git root.
base: ubuntu@${VERSION_ID}
build-base: ubuntu@${VERSION_ID}
platforms:
amd64:
parts:
charm:
plugin: dump
source: .
shared-lib:
plugin: dump
source: ../shared
organize:
"*": shared/
EOF

cd /tmp/monorepo/charm
charmcraft pack

arch=$(dpkg --print-architecture)
artifact=/tmp/monorepo/charm/monorepo-test-charm_${arch}.charm
test -f "${artifact}"
Comment on lines +51 to +53

mkdir /tmp/monorepo/unpacked
unzip -q "${artifact}" -d /tmp/monorepo/unpacked
test -f /tmp/monorepo/unpacked/shared/mylib/__init__.py
grep "GREETING" /tmp/monorepo/unpacked/shared/mylib/__init__.py

restore: |
cd /tmp/monorepo/charm 2>/dev/null && charmcraft clean || true
rm -rf /tmp/monorepo
70 changes: 21 additions & 49 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.