Skip to content

Commit b9b1fec

Browse files
committed
feat: add template for kubimo
1 parent 2283b6c commit b9b1fec

File tree

18 files changed

+462
-50
lines changed

18 files changed

+462
-50
lines changed

.dockerignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/target
2+
.env*
3+
.venv
4+
dist
5+
__pycache__/
6+
*.so

.github/workflows/cd.yaml

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ jobs:
128128
permissions:
129129
contents: read
130130
packages: write
131-
needs: release
132131
steps:
133132
- uses: actions/checkout@v4
134133
- name: Docker setup
@@ -139,27 +138,30 @@ jobs:
139138
registry: ghcr.io
140139
username: ${{ github.actor }}
141140
password: ${{ secrets.GITHUB_TOKEN }}
142-
- name: Docker meta
143-
id: meta
141+
- name: Docker meta kubimo
142+
id: meta-kubimo
144143
uses: docker/metadata-action@v5
145144
with:
146-
images: ghcr.io/aqora-io/cli
147-
flavor: |
148-
latest=false
145+
images: ghcr.io/aqora-io/cli-kubimo
146+
bake-target: docker-metadata-kubimo
149147
tags: |
150-
type=schedule
151-
type=ref,event=branch,prefix=${{ env.TAG_PREFIX }}branch-
152-
type=ref,event=tag,prefix=${{ env.TAG_PREFIX }}tag-
153-
type=ref,event=pr,prefix=${{ env.TAG_PREFIX }}pr-
154-
type=raw,value=latest,prefix=${{ env.TAG_PREFIX }},enable={{is_default_branch}}
155-
- name: Docker build and push
156-
uses: docker/build-push-action@v5
157-
with:
158-
push: ${{ github.event_name != 'pull_request' }}
159-
tags: ${{ steps.meta.outputs.tags }}
160-
labels: ${{ steps.meta.outputs.labels }}
161-
cache-from: type=gha
162-
cache-to: type=gha,mode=max
148+
type=ref,event=branch
149+
type=ref,event=pr
150+
type=semver,pattern={{version}}
151+
type=semver,pattern={{major}}.{{minor}}
152+
type=semver,pattern={{major}}
153+
- name: Build and push
154+
uses: docker/bake-action@v6
155+
with:
156+
set: |
157+
kubimo*.cache-from=type=registry,ref=ghcr.io/aqora-io/cli-kubimo:latest
158+
*.cache-to=type=inline
159+
files: |
160+
./docker-bake.hcl
161+
cwd://${{ steps.meta-kubimo.outputs.bake-file }}
162+
# TODO: change before merging
163+
# push: ${{ github.event_name != 'pull_request' }}
164+
push: true
163165

164166
npm:
165167
name: Build and publish npm package

Dockerfile

Lines changed: 0 additions & 7 deletions
This file was deleted.

docker-bake.dev.hcl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
variable "TAG" {
2+
default = "dev"
3+
}
4+
5+
target "docker-metadata-kubimo" {
6+
tags = ["ghcr.io/aqora-io/cli-kubimo:${TAG}"]
7+
}
8+

docker-bake.hcl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
group "default" {
2+
targets = ["kubimo"]
3+
}
4+
5+
target "docker-metadata-kubimo" {}
6+
7+
target "kubimo" {
8+
inherits = ["docker-metadata-kubimo"]
9+
context = "."
10+
dockerfile = "docker/Dockerfile.kubimo"
11+
}

docker/Dockerfile.kubimo

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM ghcr.io/aqora-io/kubimo-marimo:main AS build
2+
3+
USER 0
4+
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y --no-update-default-toolchain
5+
ENV PATH="/root/.cargo/bin:${PATH}"
6+
7+
WORKDIR /build
8+
COPY rust-toolchain .
9+
RUN rustc --version
10+
COPY . .
11+
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
12+
--mount=type=cache,target=/usr/local/cargo/git,sharing=locked \
13+
--mount=type=cache,target=target,sharing=locked \
14+
cargo build --release \
15+
&& cp target/release/aqora /bin/aqora
16+
17+
WORKDIR /workspace
18+
RUN aqora new dataset-marimo user/workspace -v 0.0.0 . && rm readme.py
19+
20+
FROM ghcr.io/aqora-io/kubimo-marimo:main
21+
22+
COPY --chown=1000:1000 ./docker/kubimo/marimo /home/me/.config/marimo
23+
COPY --from=build /bin/aqora /bin/aqora
24+
COPY --chown=1000:1000 --from=build /workspace/* .
25+
RUN uv venv && uv sync

docker/kubimo/marimo/marimo.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Noto+Sans+Mono:[email protected]&display=swap");
2+
3+
:root {
4+
--background: hsl(0 0% 99.2%);
5+
--marimo-monospace-font: "Noto Sans Mono", monospace;
6+
--marimo-text-font: "Inter", sans-serif;
7+
--marimo-heading-font: "Inter", sans-serif;
8+
}
9+
10+
#App[data-config-width="full"] > div {
11+
padding-inline: calc(var(--spacing, 0.25rem) * 10);
12+
}
13+
14+
#App[data-config-width="full"][data-command="run"] > div {
15+
padding-left: 0;
16+
padding-top: 0;
17+
}

docker/kubimo/marimo/marimo.toml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
[completion]
2+
activate_on_typing = true
3+
copilot = false
4+
5+
[language_servers.ty]
6+
enabled = true
7+
8+
[language_servers.basedpyright]
9+
10+
[language_servers.pylsp]
11+
enable_pyflakes = false
12+
enable_mypy = true
13+
enabled = false
14+
enable_pylint = false
15+
enable_flake8 = false
16+
enable_pydocstyle = false
17+
enable_ruff = true
18+
19+
[save]
20+
format_on_save = false
21+
autosave = "after_delay"
22+
autosave_delay = 1000
23+
24+
[runtime]
25+
auto_reload = "off"
26+
std_stream_max_bytes = 1000000
27+
reactive_tests = true
28+
watcher_on_save = "lazy"
29+
output_max_bytes = 8000000
30+
default_auto_download = ["html"]
31+
on_cell_change = "autorun"
32+
auto_instantiate = false
33+
default_sql_output = "auto"
34+
dotenv = [".env"]
35+
36+
[package_management]
37+
manager = "uv"
38+
39+
[formatting]
40+
line_length = 79
41+
42+
[diagnostics]
43+
enabled = false
44+
45+
[ai]
46+
rules = ""
47+
mode = "manual"
48+
49+
[ai.models]
50+
custom_models = []
51+
displayed_models = []
52+
53+
[experimental]
54+
55+
[keymap]
56+
preset = "default"
57+
destructive_delete = true
58+
59+
[keymap.overrides]
60+
61+
[display]
62+
default_table_max_columns = 50
63+
default_table_page_size = 10
64+
cell_output = "below"
65+
default_width = "full"
66+
theme = "light"
67+
code_editor_font_size = 14
68+
dataframes = "rich"
69+
reference_highlighting = false
70+
custom_css = ["/home/me/.config/marimo/marimo.css"]
71+
72+
[server]
73+
follow_symlink = false
74+
browser = "default"
75+
76+
[snippets]
77+
include_default_snippets = true
78+
custom_paths = []

src/commands/new/dataset_marimo.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::path::PathBuf;
2+
3+
use aqora_template::DatasetMarimoTemplate;
4+
use clap::Args;
5+
use graphql_client::GraphQLQuery;
6+
use serde::Serialize;
7+
8+
use crate::commands::GlobalArgs;
9+
use crate::error::{self, format_permission_error, Result};
10+
use crate::graphql_client::custom_scalars::*;
11+
12+
#[derive(Args, Debug, Serialize)]
13+
pub struct DatasetMarimo {
14+
#[arg(short, long)]
15+
version: Option<String>,
16+
slug: String,
17+
dest: Option<PathBuf>,
18+
}
19+
20+
#[derive(GraphQLQuery)]
21+
#[graphql(
22+
query_path = "src/graphql/get_latest_dataset_version.graphql",
23+
schema_path = "schema.graphql",
24+
response_derives = "Debug"
25+
)]
26+
pub struct GetLatestDatasetVersion;
27+
28+
pub async fn dataset_marimo(args: DatasetMarimo, global: GlobalArgs) -> Result<()> {
29+
let pb = global.spinner().with_message(format!(
30+
"Creating dataset marimo notebook for '{}'",
31+
args.slug
32+
));
33+
34+
let (owner, local_slug) = args
35+
.slug
36+
.split_once('/')
37+
.ok_or_else(|| error::user("Malformed slug", "Expected a slug like: {owner}/{dataset}"))?;
38+
39+
let version = if let Some(version) = args.version {
40+
version
41+
} else {
42+
global
43+
.graphql_client()
44+
.await?
45+
.send::<GetLatestDatasetVersion>(get_latest_dataset_version::Variables {
46+
owner: owner.to_string(),
47+
local_slug: local_slug.to_string(),
48+
})
49+
.await?
50+
.dataset_by_slug
51+
.and_then(|d| d.latest_version)
52+
.map(|v| v.version)
53+
.ok_or_else(|| {
54+
error::user(
55+
"No version found",
56+
"Please publish a version or specify a draft version",
57+
)
58+
})?
59+
};
60+
61+
let dest = args.dest.unwrap_or_else(|| PathBuf::from(local_slug));
62+
DatasetMarimoTemplate::builder()
63+
.owner(owner)
64+
.local_slug(local_slug)
65+
.version(version)
66+
.render(&dest)
67+
.map_err(|e| format_permission_error("create use case", &dest, &e))?;
68+
69+
pb.finish_with_message(format!(
70+
"Created dataset marimo noteboook in '{}'",
71+
dest.display()
72+
));
73+
Ok(())
74+
}

src/commands/new/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod dataset_marimo;
12
mod use_case;
23

34
use clap::Subcommand;
@@ -7,15 +8,19 @@ use crate::error::Result;
78

89
use super::GlobalArgs;
910

11+
use dataset_marimo::{dataset_marimo, DatasetMarimo};
1012
use use_case::{use_case, UseCase};
1113

1214
#[derive(Subcommand, Debug, Serialize)]
1315
pub enum New {
1416
UseCase(UseCase),
17+
#[clap(hide = true)]
18+
DatasetMarimo(DatasetMarimo),
1519
}
1620

1721
pub async fn new(args: New, global: GlobalArgs) -> Result<()> {
1822
match args {
1923
New::UseCase(args) => use_case(args, global).await,
24+
New::DatasetMarimo(args) => dataset_marimo(args, global).await,
2025
}
2126
}

0 commit comments

Comments
 (0)