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
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ updates:
labels:
- "skip issue"
- "skip news"
- package-ecosystem: "docker"
directory: "/.nanvix/docker"
schedule:
interval: "monthly"
labels:
- "skip issue"
- "skip news"
59 changes: 59 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright(c) The Maintainers of Nanvix.
# Licensed under the MIT License.

name: Docker Image

on:
push:
branches: ["nanvix/**"]
paths:
- ".nanvix/docker/Dockerfile"
- ".github/workflows/docker-image.yml"
pull_request:
branches: ["nanvix/**"]
paths:
- ".nanvix/docker/Dockerfile"
- ".github/workflows/docker-image.yml"
workflow_dispatch:

permissions:
contents: read

env:
REGISTRY: ghcr.io
IMAGE_NAME: nanvix/toolchain-python

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4

- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=sha-
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .nanvix/docker
file: .nanvix/docker/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
34 changes: 15 additions & 19 deletions .github/workflows/nanvix-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ permissions:
actions: write
issues: write
pull-requests: write
packages: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref_name || github.ref || 'default' }}
Expand All @@ -25,13 +26,13 @@ concurrency:
jobs:
ci:
if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
uses: nanvix/workflows/.github/workflows/nanvix-ci.yml@v1.14.0
uses: nanvix/workflows/.github/workflows/nanvix-ci.yml@v2.0.1
with:
zutil-version: "v0.7.48"
zutil-version: "v0.8.5"
docker-image: "ghcr.io/nanvix/toolchain-python:latest"
platforms: '["microvm"]'
memory-sizes: '["256mb"]'
matrix-exclude: '[{"platform":"hyperlight"}]'
windows-matrix-exclude: '[{"platform":"hyperlight"}]'
windows-matrix-exclude: '[]'
skip-full-test-modes: '[]'
caller-event-name: ${{ github.event_name }}
windows-test: true
Expand All @@ -41,18 +42,13 @@ jobs:

ci-scheduled:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
permissions:
contents: write
actions: write
issues: write
pull-requests: write
uses: nanvix/workflows/.github/workflows/nanvix-ci.yml@v1.14.0
uses: nanvix/workflows/.github/workflows/nanvix-ci.yml@v2.0.1
with:
zutil-version: "v0.7.48"
zutil-version: "v0.8.5"
docker-image: "ghcr.io/nanvix/toolchain-python:latest"
platforms: '["microvm"]'
memory-sizes: '["256mb"]'
matrix-exclude: '[{"platform":"hyperlight"}]'
windows-matrix-exclude: '[{"platform":"hyperlight"}]'
windows-matrix-exclude: '[]'
skip-full-test-modes: '[]'
caller-event-name: 'schedule'
windows-test: true
Expand All @@ -62,7 +58,7 @@ jobs:

# -------------------------------------------------------------------
# Create a Windows zip release asset for MXC consumption.
# The reusable workflow creates a GitHub release with .tar.bz2 assets.
# The reusable workflow creates a GitHub release with .tar.gz assets.
# This job downloads the standalone tarball from that release, extracts
# python.elf + cpython-ramfs.img, packs them into a flat .zip, and
# uploads it to the same release.
Expand Down Expand Up @@ -94,7 +90,7 @@ jobs:
sleep 5

# Download standalone tarballs (exclude buildroot variant)
gh release download "$RELEASE_TAG" --pattern "*standalone*.tar.bz2" --dir release-download || true
gh release download "$RELEASE_TAG" --pattern "*standalone*.tar.gz" --dir release-download || true
ls -la release-download/

- name: Create Windows zip
Expand All @@ -104,7 +100,7 @@ jobs:
set -euo pipefail

# Find the main standalone tarball (not buildroot)
TARBALL=$(find release-download -name "*standalone*.tar.bz2" ! -name "*buildroot*" | head -1)
TARBALL=$(find release-download -name "*standalone*.tar.gz" ! -name "*buildroot*" | head -1)
if [[ -z "$TARBALL" ]]; then
echo "::warning::No standalone tarball found (excluding buildroot)"
ls release-download/ 2>/dev/null || true
Expand All @@ -113,7 +109,7 @@ jobs:
echo "Using tarball: $TARBALL"

mkdir -p extract windows-zip
tar -xjf "$TARBALL" -C extract
tar -xzf "$TARBALL" -C extract

# Find the python binary — it's at bin/python.elf
PYTHON_ELF=$(find extract -name "python.elf" -type f | head -1)
Expand Down Expand Up @@ -153,10 +149,10 @@ jobs:
curl -fsSL https://raw.githubusercontent.com/nanvix/nanvix/refs/heads/dev/scripts/get-nanvix.sh \
| bash -s -- --force nanvix-dl
MKRAMFS=""
NVX_TAR=$(find nanvix-dl -name "nanvix-microvm-standalone-*.tar.bz2" | head -1)
NVX_TAR=$(find nanvix-dl -name "nanvix-microvm-standalone-*.tar.gz" | head -1)
if [[ -n "$NVX_TAR" ]]; then
mkdir -p nanvix-extract
tar -xjf "$NVX_TAR" -C nanvix-extract
tar -xzf "$NVX_TAR" -C nanvix-extract
MKRAMFS=$(find nanvix-extract -name "mkramfs.elf" -type f | head -1)
fi

Expand Down
2 changes: 1 addition & 1 deletion .nanvix/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Platform defaults
# ---------------------------------------------------------------------------

DOCKER_IMAGE = "nanvix/toolchain:latest-minimal"
DOCKER_IMAGE = "ghcr.io/nanvix/toolchain-python:latest"
DEFAULT_PLATFORM = "microvm"
DEFAULT_PROCESS_MODE = "standalone"
DEFAULT_MEMORY_SIZE = "256mb"
Expand Down
14 changes: 14 additions & 0 deletions .nanvix/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright(c) The Maintainers of Nanvix.
# Licensed under the MIT License.

# toolchain-python — Nanvix GCC toolchain + host Python 3 for CPython
# cross-compilation. Published as ghcr.io/nanvix/toolchain-python.

FROM ghcr.io/nanvix/toolchain-gcc:sha-34a3641

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
python3 \
python3-dev \
&& rm -rf /var/lib/apt/lists/* \
&& ln -sf /usr/bin/python3 /opt/nanvix/bin/python3
Comment on lines +11 to +14
2 changes: 1 addition & 1 deletion .nanvix/nanvix.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cpython"
version = "3.12.3"
nanvix-version = "0.12.536"
nanvix-version = "0.13.16"

[builds]
[builds.matrix]
Expand Down
22 changes: 11 additions & 11 deletions .nanvix/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ def package(
"""Package CPython release tarballs.

Creates two tarballs in ``dist/``:
- ``cpython-<platform>-<mode>-<memory>.tar.bz2`` — runtime sysroot + binary + ramfs
- ``cpython-<platform>-<mode>-<memory>-buildroot.tar.bz2`` — build dependencies
- ``cpython-<platform>-<mode>-<memory>.tar.gz`` — runtime sysroot + binary + ramfs
- ``cpython-<platform>-<mode>-<memory>-buildroot.tar.gz`` — build dependencies

Args:
nanvix_home: Host-side path to the Nanvix sysroot for local
Expand Down Expand Up @@ -187,25 +187,25 @@ def package(
dist_dir.mkdir(parents=True, exist_ok=True)

# Sysroot tarball.
sysroot_tar = dist_dir / f"{artifact}.tar.bz2"
sysroot_tar = dist_dir / f"{artifact}.tar.gz"
sysroot_runtime = ramfs_staging / "sysroot"
with tarfile.open(str(sysroot_tar), "w:bz2") as tf:
with tarfile.open(str(sysroot_tar), "w:gz") as tf:
tf.add(str(sysroot_runtime), arcname="sysroot")
if bin_dir.is_dir():
tf.add(str(bin_dir), arcname="bin")
if ramfs_img.is_file():
tf.add(str(ramfs_img), arcname="cpython-ramfs.img")

# Buildroot tarball.
buildroot_tar = dist_dir / f"{artifact}-buildroot.tar.bz2"
with tarfile.open(str(buildroot_tar), "w:bz2") as tf:
buildroot_tar = dist_dir / f"{artifact}-buildroot.tar.gz"
with tarfile.open(str(buildroot_tar), "w:gz") as tf:
tf.add(str(buildroot_pkg), arcname="sysroot")

# Cleanup staging.
shutil.rmtree(release_staging)

print("Release tarballs created in dist/")
for f in sorted(dist_dir.glob(f"{artifact}*.tar.bz2")):
for f in sorted(dist_dir.glob(f"{artifact}*.tar.gz")):
size = f.stat().st_size
print(f" {f.name} ({size // 1024}K)")

Expand All @@ -227,18 +227,18 @@ def verify(

print("Verifying release tarballs...")

sysroot_tar = dist_dir / f"{artifact}.tar.bz2"
buildroot_tar = dist_dir / f"{artifact}-buildroot.tar.bz2"
sysroot_tar = dist_dir / f"{artifact}.tar.gz"
buildroot_tar = dist_dir / f"{artifact}-buildroot.tar.gz"

if not sysroot_tar.is_file():
raise FileNotFoundError(f"Sysroot tarball not found: {sysroot_tar}")
if not buildroot_tar.is_file():
raise FileNotFoundError(f"Buildroot tarball not found: {buildroot_tar}")

# Verify integrity.
with tarfile.open(str(sysroot_tar), "r:bz2") as tf:
with tarfile.open(str(sysroot_tar), "r:gz") as tf:
members = tf.getnames()
with tarfile.open(str(buildroot_tar), "r:bz2") as tf:
with tarfile.open(str(buildroot_tar), "r:gz") as tf:
_ = tf.getnames()

# Verify python.elf is present (exact path match).
Expand Down
30 changes: 18 additions & 12 deletions .nanvix/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,27 @@ def _download_release_as_cache(
tag = release["tag_name"]
print(f" Resolved cpython release: {tag}")

# Find a standalone tarball asset.
# Find a standalone tarball asset (.tar.gz preferred, .tar.bz2 fallback).
asset_prefix = f"cpython-{platform}-{process_mode}-{memory_size}"
asset_url = None
asset_name = None
for a in release.get("assets", []):
name = a.get("name", "")
if (
name.startswith(asset_prefix)
and name.endswith(".tar.bz2")
and "buildroot" not in name
):
asset_url = a["browser_download_url"]
asset_name = name
for ext in (".tar.gz", ".tar.bz2"):
for a in release.get("assets", []):
name = a.get("name", "")
if (
name.startswith(asset_prefix)
and name.endswith(ext)
and "buildroot" not in name
):
asset_url = a["browser_download_url"]
asset_name = name
break
if asset_url:
break

if not asset_url:
raise FileNotFoundError(
f"No cpython release asset matching '{asset_prefix}*.tar.bz2' "
f"No cpython release asset matching '{asset_prefix}*.tar.gz' or '*.tar.bz2' "
f"in release {tag}. Available assets: "
Comment on lines +94 to 95
+ ", ".join(a["name"] for a in release.get("assets", []))
)
Expand All @@ -104,7 +107,7 @@ def _download_release_as_cache(

# Extract into _install_cache with path-traversal protection.
print(f" Extracting to {cache_dir}...")
with tarfile.open(tarball, "r:bz2") as tf:
with tarfile.open(tarball, "r:*") as tf:
base = cache_dir.resolve()
for member in tf.getmembers():
if member.issym() or member.islnk():
Expand Down Expand Up @@ -718,6 +721,7 @@ def run_all(
release: bool = False,
test_list: list[str] | None = None,
batch_size: int = config.DEFAULT_TEST_BATCH_SIZE,
nanvixd_extra: list[str] | None = None,
run_fn: Any = None,
docker: bool = False,
) -> None:
Expand Down Expand Up @@ -751,6 +755,7 @@ def run_all(
staging,
process_mode=process_mode,
platform=platform,
nanvixd_extra=nanvixd_extra,
ramfs_img=ramfs_img,
nanvix_home=nanvix_home,
)
Expand All @@ -763,6 +768,7 @@ def run_all(
platform=platform,
test_list=test_list,
batch_size=batch_size,
nanvixd_extra=nanvixd_extra,
ramfs_img=ramfs_img,
release=release,
)
Expand Down
Loading
Loading