Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5011a3d
Add supercharm wrapper
arturo-seijas Feb 25, 2026
7b6b6c2
Add context
arturo-seijas Feb 25, 2026
9c9244f
Refactor
arturo-seijas Feb 25, 2026
6686f79
Remove boilerplate
arturo-seijas Mar 9, 2026
72a7bf6
changelog
arturo-seijas Mar 9, 2026
fca895f
Merge branch 'main' into charmcraft-wrapper
arturo-seijas Mar 9, 2026
d9ef610
Update workflows
arturo-seijas Mar 9, 2026
53e2712
Simplify
arturo-seijas Mar 9, 2026
1e8e9be
Rename package
arturo-seijas Mar 9, 2026
b20d063
fix linting
arturo-seijas Mar 9, 2026
aba15b4
changelog
arturo-seijas Mar 9, 2026
43a618e
Fix install
arturo-seijas Mar 9, 2026
3c0a8ee
Fix install
arturo-seijas Mar 9, 2026
2e75454
Fix installation
arturo-seijas Mar 9, 2026
d1b00a9
Fix installation
arturo-seijas Mar 9, 2026
825ee2a
Fix installation
arturo-seijas Mar 9, 2026
296ac92
Fix installation
arturo-seijas Mar 9, 2026
ac765d7
Merge branch 'main' into charmcraft-wrapper
arturo-seijas Mar 10, 2026
f92f679
build
arturo-seijas Mar 10, 2026
2c664fe
Fix gitignore
arturo-seijas Mar 10, 2026
b33fe69
Fix gitignore
arturo-seijas Mar 10, 2026
a5e2953
Fix gitignore
arturo-seijas Mar 10, 2026
fa3ee60
rename
arturo-seijas Mar 10, 2026
743c111
build
arturo-seijas Mar 10, 2026
27e1f96
fix checkout
arturo-seijas Mar 10, 2026
0a59491
rocks
arturo-seijas Mar 10, 2026
0fd3581
build
arturo-seijas Mar 10, 2026
7108b1e
changelog
arturo-seijas Mar 10, 2026
94b63cd
headers
arturo-seijas Mar 10, 2026
ffee6e8
Apply suggestions from code review
arturo-seijas Mar 10, 2026
b0d586c
try local install
arturo-seijas Mar 10, 2026
14c24c9
fix ref
arturo-seijas Mar 10, 2026
fd60699
change ref
arturo-seijas Mar 10, 2026
0170c1b
Merge remote-tracking branch 'origin/main' into charmcraft-wrapper
arturo-seijas Mar 11, 2026
4a070c6
fix changelog
arturo-seijas Mar 11, 2026
637400b
Merge branch 'main' into charmcraft-wrapper
arturo-seijas Mar 17, 2026
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
17 changes: 3 additions & 14 deletions .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ on:
description: Label for building the charm
type: string
default: ubuntu-latest
charmcraftcache:
description: Use charmcraftcache (https://github.com/canonical/charmcraftcache)
type: boolean
default: false
charmcraft-channel:
description: Charmcraft channel to use for the integration test
type: string
default: latest/stable
channel:
description: Actions operator provider channel as per https://github.com/charmed-kubernetes/actions-operator#usage
type: string
Expand Down Expand Up @@ -264,20 +256,17 @@ jobs:
if: ${{ inputs.rockcraft-enable-security-nesting }}
run: |
lxc profile set default security.nesting true
- name: Install charmcraftcache
if: ${{ inputs.charmcraftcache }}
- name: Install builder
run: |
pipx install charmcraftcache
pipx install git+https://github.com/canonical/superbuild@0.1.0
- uses: actions/checkout@v6.0.2
- name: Pre-build script
if: ${{ inputs.pre-build-script != '' }}
run: bash -xe ${{ inputs.pre-build-script }}
- uses: canonical/operator-workflows/internal/build@main
- uses: canonical/operator-workflows/internal/build@charmcraft-wrapper
id: build
with:
build-plan: ${{ toJSON(matrix.build) }}
charmcraftcache: ${{ inputs.charmcraftcache }}
charmcraft-channel: ${{ inputs.charmcraft-channel }}
github-token: ${{ secrets.GITHUB_TOKEN }}
rockcraft-channel: ${{ inputs.rockcraft-channel }}

Expand Down
58 changes: 13 additions & 45 deletions dist/build/index.js

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

2 changes: 1 addition & 1 deletion dist/build/index.js.map

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

Each revision is versioned by the date of the revision.

## 2026-03-11

- Build charms using the charmcraft wrapper.

## 2026-03-10

- Drop support for charmcraftcache
- Drop leftover registry input.

## 2026-03-09
Expand Down
6 changes: 0 additions & 6 deletions internal/build/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ inputs:
build-plan:
description: Build plan.
required: true
charmcraftcache:
description: Use charmcraftcache (https://github.com/canonical/charmcraftcache)
default: "false"
charmcraft-channel:
description: Charmcraft channel to use for the integration test
default: latest/stable
github-token:
description: github token.
required: true
Expand Down
1 change: 0 additions & 1 deletion package-lock.json

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

47 changes: 19 additions & 28 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import path from 'path'

interface BuildCharmParams {
plan: BuildPlan
charmcraftChannel: string
}

async function gitTreeId(p: string): Promise<string> {
Expand All @@ -29,32 +28,25 @@ async function gitTreeId(p: string): Promise<string> {
}

async function buildCharm(params: BuildCharmParams): Promise<void> {
if (params.charmcraftChannel) {
await exec.exec('sudo', [
'snap',
'install',
'charmcraft',
'--channel',
params.charmcraftChannel,
'--classic'
])
} else {
await exec.exec('sudo', ['snap', 'install', 'charmcraft', '--classic'])
}
core.startGroup('charmcraft pack')
const charmcraftBin = core.getBooleanInput('charmcraftcache')
? 'ccc'
: 'charmcraft'
await exec.exec(charmcraftBin, ['pack', '--verbosity', 'trace'], {
cwd: params.plan.source_directory,
env: { ...process.env, CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS: 'true' }
})
core.startGroup('superbuild pack')
await exec.exec(
'superbuild',
[
'pack',
'--verbose',
'--build-context',
'.',
'--project-dir',
params.plan.source_directory
],
{
env: { ...process.env, CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS: 'true' }
}
)
core.endGroup()
const charmFiles = await (
await glob.create(path.join(params.plan.source_directory, '*.charm'))
).glob()
const charmFiles = await (await glob.create(path.join('.', '*.charm'))).glob()
const artifact = new DefaultArtifactClient()
const manifestFile = path.join(params.plan.source_directory, 'manifest.json')
const manifestFile = path.join('.', 'manifest.json')
fs.writeFileSync(
manifestFile,
JSON.stringify(
Expand All @@ -66,7 +58,7 @@ async function buildCharm(params: BuildCharmParams): Promise<void> {
await artifact.uploadArtifact(
params.plan.output,
[...charmFiles, manifestFile],
params.plan.source_directory
'.'
)
}

Expand Down Expand Up @@ -356,8 +348,7 @@ export async function run(): Promise<void> {
switch (plan.type) {
case 'charm':
await buildCharm({
plan,
charmcraftChannel: core.getInput('charmcraft-channel')
plan
})
break
case 'docker-image':
Expand Down
3 changes: 3 additions & 0 deletions superbuild/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build
*.egg-info
**/__pycache__/
70 changes: 70 additions & 0 deletions superbuild/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# superbuild

`superbuild` is a thin Python wrapper around [charmcraft](https://juju.is/docs/sdk/charmcraft).
It ensures `charmcraft` is installed on the machine and transparently forwards all arguments to it,
with one extra convenience: a `--build-context` option that lets you supply an external directory
of source files to include in the build without modifying your project tree.

## Features

- Auto-installs the latest `charmcraft` via `snap` if it is not already present.
- Accepts an optional `--build-context <dir>` argument (see below).
- All other arguments and flags are passed through to `charmcraft` unchanged.
- After the build, any `.charm` files whose name matches the `name` key in `charmcraft.yaml`
are copied back to the current working directory automatically.

## Requirements

- Python 3.8+
- `snap` (for automatic `charmcraft` installation)
- `pyyaml` (installed automatically as a dependency)

## Installation

```bash
pip install ./superbuild
```

Or, for development:

```bash
pip install -e ./superbuild
```

## Usage

```
superbuild [--build-context <dir>] <charmcraft command and args>
```

### Without `--build-context`

`superbuild` behaves exactly like calling `charmcraft` directly:

```bash
superbuild pack
superbuild version
superbuild upload my-charm_ubuntu-22.04-amd64.charm
```

### With `--build-context`

Provide a directory whose contents will be merged with the `charmcraft.yaml` from the current
working directory into a temporary build directory. This is useful when your source files live
separately from your charm metadata.

```bash
superbuild --build-context ./src pack
```

What happens internally:

1. A temporary directory is created.
2. `charmcraft.yaml` from the **current working directory** (if present) is copied in.
3. All files and subdirectories from `--build-context` are copied in alongside it.
4. `charmcraft` is executed with the remaining arguments inside that temporary directory.
5. Any resulting `.charm` files whose filename starts with the charm `name` are copied back
to the current working directory.
6. The temporary directory is cleaned up.

If `--build-context` is omitted, the current working directory is used as the context.
19 changes: 19 additions & 0 deletions superbuild/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2026 Canonical Ltd.
# See LICENSE file for licensing details.

[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[project]
name = "superbuild"
version = "0.1.0"
description = "Thin wrapper that ensures charmcraft is installed and forwards all arguments to it"
requires-python = ">=3.8"
dependencies = ["pyyaml"]

[tool.pytest.ini_options]
testpaths = ["tests"]

[project.scripts]
superbuild = "superbuild.main:main"
5 changes: 5 additions & 0 deletions superbuild/superbuild/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python3

# Copyright 2025 Canonical Ltd.
# See LICENSE file for licensing details.

Loading
Loading