This is an automated email from the ASF dual-hosted git repository.

d4rkstar pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/openserverless.git


The following commit(s) were added to refs/heads/main by this push:
     new e506d3f  Source release first preview (#202)
e506d3f is described below

commit e506d3fc4c5697d59e2aa44eb7daf4d3968d8ae7
Author: Michele Sciabarra <[email protected]>
AuthorDate: Mon Jul 6 14:24:31 2026 +0200

    Source release first preview (#202)
    
    * lima config
    
    * taskfile
    
    * java instructions
    
    * Point build submodule to local openwhisk update
    
    * Update build submodule for Nuvolaris openwhisk source
    
    * Update devcontainer with OpenWhisk build tools
    
    * Revert "Update devcontainer with OpenWhisk build tools"
    
    This reverts commit b4f55bc5079a20e65ba2b431e80e8431c2998942.
    
    * Update build submodule devcontainer toolchain
    
    * Update build distdocker local workflow
    
    * Update build distdocker container wrapper
    
    * Update build-all local workflow
    
    * Document and wire local kind build workflow
    
    * Use task build as local workflow entrypoint
    
    * build updated
    
    * Document ops devcontainer build flow
    
    * Vendor OpenWhisk in build workflow
    
    * Track build submodule main branch
    
    * Track build submodule build-local branch
    
    * add openserverless
    
    * Update build submodule for ARM protoc
    
    * Update build submodule for buildx-all
    
    * Update build submodule for buildx setup
    
    * Update build submodule for local buildx registry
    
    * taskfile
    
    * sync refs
    
    * build-and-test
    
    * correct attributes
    
    * remving site
    
    * build-and-test
    
    * avoid issue with snap
    
    * fixes mac
    
    * assume docker
    
    * making executable mount
    
    * mount writable
    
    * sync
    
    * sync
    
    * build-and-test windows
    
    * reorder task
    
    * update
    
    ---------
    
    Co-authored-by: Trustable User <[email protected]>
    Co-authored-by: Michele Sciabarra <[email protected]>
    Co-authored-by: Michele Sciabarra <[email protected]>
---
 .gitattributes                         |   5 +
 .gitmodules                            |   8 +-
 README.md                              |   5 +-
 Taskfile.yml                           |  78 ++++++--
 admin-api                              |   2 +-
 build                                  |   1 +
 build-and-test-mac.sh                  |  70 +++++++
 build-and-test-ubuntu.sh               |  83 ++++++++
 build-and-test-windows.ps1             | 136 +++++++++++++
 build-step.md                          | 356 +++++++++++++++++++++++++++++++++
 cli                                    |   2 +-
 devcontainer                           |   2 +-
 olaris                                 |   2 +-
 olaris-op                              |   2 +-
 openserverless-cli.code-workspace      |  21 --
 openserverless-operator.code-workspace |  17 --
 openserverless.code-workspace          |  24 ---
 runtimes                               |   2 +-
 site                                   |   1 -
 streamer                               |   2 +-
 testing                                |   2 +-
 vscode                                 |   2 +-
 22 files changed, 727 insertions(+), 96 deletions(-)

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..f7b2686
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+* text=auto eol=lf
+*.sh text eol=lf
+*.ps1 text eol=crlf
+*.png binary
+*.jpg binary
diff --git a/.gitmodules b/.gitmodules
index b608813..956b4a2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,7 +1,3 @@
-[submodule "site"]
-       path = site
-       url = https://github.com/apache/openserverless-site
-       branch = main
 [submodule "cli"]
        path = cli
        url = https://github.com/apache/openserverless-cli
@@ -38,3 +34,7 @@
        path = admin-api
        url = https://github.com/apache/openserverless-admin-api
         branch = main
+[submodule "build"]
+       path = build
+       url = https://github.com/apache/openserverless-build
+       branch = build-local
diff --git a/README.md b/README.md
index 0a39f51..097e190 100644
--- a/README.md
+++ b/README.md
@@ -38,10 +38,13 @@ Access the distro (`wsl -d Ubuntu-24.04` ), configure a new 
user,  then execute:
 
 ```
 sudo apt-get update
-sudo apt-get -y install jq
+sudo apt-get -y install jq unzip zip
 sudo snap install go --classic
 sudo snap install task --classic
 sudo snap install kubectl --classic
+curl -s "https://get.sdkman.io"; | bash
+source "/home/msciab/.sdkman/bin/sdkman-init.sh"
+sdk install java 17.0.19-tem
 ```
 
 ## Prepare Ubuntu Linux
diff --git a/Taskfile.yml b/Taskfile.yml
index c0be831..ae0f099 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -16,6 +16,11 @@ vars:
 
   RUNTIMES_TAG: "{{.OPERATOR_TAG}}"
 
+  OPENSERVERLESS_TAG: "{{.OPERATOR_TAG}}"
+  CONTROLLER_SRC: 
"docker.io/apache/openserverless-wsk-invoker:{{.OPENSERVERLESS_TAG}}"
+  INVOKER_SRC: 
"docker.io/apache/openserverless-wsk-controller:{{.OPENSERVERLESS_TAG}}"
+
+  OPS_BRANCH: "{{.OPERATOR_TAG}}"
 
 tasks:
 
@@ -50,6 +55,7 @@ tasks:
       status:
       - ! test -e ../ops
 
+
     operator:
       desc: build the operator
       deps:
@@ -77,7 +83,6 @@ tasks:
         vars:
           SRC: "{{.STREAMER_SRC}}"
 
-
     admin-api:
       desc: build the admin-api
       deps:
@@ -92,18 +97,25 @@ tasks:
         vars:
           SRC: "{{.ADMIN_API_SRC}}"
 
-    opsroot:
-      desc: build current opsroot.json
-      dir: olaris
+    openserverless:
+      desc: build openserverless
+      dir: build
+      env:
+        PATH: "{{.TASKFILE_DIR}}:$PATH"
+        OPS_ROOT: "{{.TASKFILE_DIR}}"
       cmds:
-      - test -e opsroot.orig || jq . <opsroot.json >opsroot.orig
-      - >
-        jq <opsroot.orig >opsroot.json  '
-          .config.images.operator = "{{.OPERATOR_SRC}}" |
-          .config.images.streamer = "{{.STREAMER_SRC}}" |
-          .config.images.systemapi = "{{.ADMIN_API_SRC}}"
-        '
-      - diff opsroot.orig opsroot.json || true
+      - echo Building  OpenServerless
+      - git tag -d $(git tag) && git tag {{.OPENSERVERLESS_TAG}}
+      - |
+        export PATH="{{.TASKFILE_DIR}}:$PATH"
+        export OPS_ROOT="{{.TASKFILE_DIR}}/olaris"
+        task build-all
+      - task: image-save
+        vars:
+          SRC: "{{.CONTROLLER_SRC}}"
+      - task: image-save
+        vars:
+          SRC: "{{.INVOKER_SRC}}"
 
     runtimes:
       desc: build current runtimes.json
@@ -121,7 +133,7 @@ tasks:
       dir: runtimes
       vars:
         IMAGES:
-          sh: jq -r '.runtimes[][] | select(.default == true) | 
"\(.image.prefix)/\(.image.name):\(.image.tag)"' runtimes.json
+          sh: jq -r '.runtimes[][] | select(.default == true) | 
"\(.image.prefix)/\(.image.name):\(.image.tag)"'   runtimes.json | grep -v php
       cmds:
       - for: { var: IMAGES, split: "\n", as: IMG }
         task: image-save
@@ -130,21 +142,49 @@ tasks:
           TGT:
             sh: echo ~/.ops/{{OS}}-{{ARCH}}/images/kind/$(echo 
docker.io/{{.IMG}} | /usr/bin/base64 -w0)
 
+    opsroot:
+      desc: build current opsroot.json
+      dir: olaris
+      cmds:
+      - test -e opsroot.orig || jq . <opsroot.json >opsroot.orig
+      - >
+        jq <opsroot.orig >opsroot.json  '
+          .config.images.operator = "{{.OPERATOR_SRC}}"   |
+          .config.images.streamer = "{{.STREAMER_SRC}}"   |
+          .config.images.systemapi = "{{.ADMIN_API_SRC}}" |
+          .config.images.controller = "{{.CONTROLLER_SRC}}" |
+          .config.images.invoker = "{{.INVOKER_SRC}}"
+        '
+      - diff opsroot.orig opsroot.json || true
+
+    opslink:
+      desc: link ops
+      cmds:
+      - task: cli
+      - mkdir -p ~/.local/bin ~/.ops/{{.OPS_BRANCH}}
+      - ln -sf $(pwd)/ops ~/.local/bin/ops
+      - ln -sf $(pwd)/olaris ~/.ops/{{.OPS_BRANCH}}/olaris
+
     build:
       desc: build all
       cmds:
-      - task: cli
+      - task: opslink
+      - task: openserverless
       - task: operator
       - task: runtimes
       - task: streamer
       - task: admin-api
       - task: opsroot
-      - task: runtimes
 
-    setup:
-      desc: setup
+    test:
+      desc: create
+      dir: testing/tests
       cmds:
         - |
-          export PATH="$PWD:$PATH" 
-          ops setup mini
+          export PATH="{{.TASKFILE_DIR}}:$PATH"
+          export OPS_ROOT="{{.TASKFILE_DIR}}/olaris"
+          export OPS_BRANCH="{{.OPS_BRANCH}}"
+          which ops
+          ops -info
+          ./all.sh kind
 
diff --git a/admin-api b/admin-api
index 650c207..395265e 160000
--- a/admin-api
+++ b/admin-api
@@ -1 +1 @@
-Subproject commit 650c2077be04509a208a71fa63b6c22f7b9918e1
+Subproject commit 395265ebff6113f712694ac9bbc7ca725e998ade
diff --git a/build b/build
new file mode 160000
index 0000000..e56fdb1
--- /dev/null
+++ b/build
@@ -0,0 +1 @@
+Subproject commit e56fdb1daed6b4bb8bb8219f2ba85fa8a561c425
diff --git a/build-and-test-mac.sh b/build-and-test-mac.sh
new file mode 100755
index 0000000..dfc6a62
--- /dev/null
+++ b/build-and-test-mac.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+set -euo pipefail
+
+VM_NAME="openserverless"
+# Mount and build in the CURRENT directory (where the script is launched from),
+# not where the script file lives.
+SRC_DIR="$(pwd)"
+LINUX_SCRIPT="build-and-test-ubuntu.sh"
+
+echo "Checking this is a Mac"
+if [[ "$(uname -s)" != "Darwin" ]]; then
+    echo "ERROR: this script must run on macOS (Darwin), found $(uname -s)" >&2
+    exit 1
+fi
+
+echo "Checking lima is installed"
+if ! command -v limactl >/dev/null 2>&1; then
+    echo "ERROR: lima (limactl) is not installed. Install it with 'brew 
install lima'" >&2
+    exit 1
+fi
+
+echo "Destroying existing '$VM_NAME' VM if it exists"
+if limactl list --quiet 2>/dev/null | grep -qx "$VM_NAME"; then
+    limactl stop -f "$VM_NAME" 2>/dev/null || true
+    limactl delete -f "$VM_NAME"
+fi
+
+echo "Creating '$VM_NAME' VM with the source dir mounted writable"
+# Mount the source directory writable so `go build` can write the ops binary
+# back into the tree (the default lima mounts are read-only).
+limactl start --name="$VM_NAME" --tty=false \
+    --cpus=4 --memory=8 \
+    --set ".mounts += [{\"location\": \"$SRC_DIR\", \"writable\": true}]"
+
+# Path of the mounted source dir as seen inside the VM (lima mirrors the host 
path).
+GUEST_SRC="$SRC_DIR"
+
+echo "Provisioning the build user (docker + passwordless sudo)"
+# The user that owns the mounted source already exists inside the VM (lima maps
+# the host user in), so reuse it rather than creating one with a clashing uid.
+# Give it docker + passwordless sudo so the build script needs no 
newgrp/usermod.
+# The resolved username is written to a file we read back on the host.
+BUILD_USER="$(limactl shell "$VM_NAME" sudo env GUEST_SRC="$GUEST_SRC" bash 
-euo pipefail <<'PROVISION'
+# uid that owns the source files on the mount -> the user we build as.
+SRC_UID="$(stat -c %u "$GUEST_SRC")"
+BUILD_USER="$(getent passwd "$SRC_UID" | cut -d: -f1)"
+if [ -z "$BUILD_USER" ]; then
+    echo "no user owns $GUEST_SRC (uid $SRC_UID)" >&2
+    exit 1
+fi
+
+# Install docker and add the build user to the docker + sudo groups.
+which docker >/dev/null 2>&1 || curl -sL get.docker.com | sh >&2
+usermod -aG docker,sudo "$BUILD_USER"
+
+# Passwordless sudo.
+echo "$BUILD_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/build-user
+chmod 440 /etc/sudoers.d/build-user
+
+echo "$BUILD_USER"
+PROVISION
+)"
+echo "Build user is '$BUILD_USER'"
+
+echo "Running $LINUX_SCRIPT inside the VM as '$BUILD_USER'"
+# Run as the build user WITHOUT -i: a login shell would reset the working dir 
to
+# the user's home. -H sets $HOME; the script cd's into the source dir itself.
+
+limactl shell --workdir "$GUEST_SRC" "$VM_NAME" sudo -H -u "$BUILD_USER" bash 
-- "$GUEST_SRC/$LINUX_SCRIPT"
diff --git a/build-and-test-ubuntu.sh b/build-and-test-ubuntu.sh
new file mode 100755
index 0000000..68fdd8c
--- /dev/null
+++ b/build-and-test-ubuntu.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+set -euo pipefail
+
+# This script builds and tests the sources. It expects to run as a user that
+# already has passwordless sudo and is a member of the docker group (the host
+# driver — build-and-test-mac.sh / build-and-test-windows.ps1 — sets that up).
+# It must run from the source directory, which the user can write to.
+
+echo "Checking this is Linux Ubuntu"
+if [[ "$(uname -s)" != "Linux" ]]; then
+    echo "ERROR: this script must run on Linux, found $(uname -s)" >&2
+    exit 1
+fi
+if ! grep -qi ubuntu /etc/os-release 2>/dev/null; then
+    echo "ERROR: this script must run on Ubuntu" >&2
+    exit 1
+fi
+
+echo "Checking Docker is accessible"
+if ! command -v docker >/dev/null 2>&1; then
+    echo "ERROR: docker is not installed" >&2
+    exit 1
+fi
+if ! docker ps >/dev/null 2>&1; then
+    echo "ERROR: cannot access the Docker daemon (permission denied or daemon 
not running)." >&2
+    echo "       Ensure the daemon is running and this user is in the 'docker' 
group." >&2
+    echo "       If you were just added to the group, start a fresh session 
(e.g. 'newgrp docker')." >&2
+    exit 1
+fi
+
+echo "Killing k3s processes if present"
+if [[ -x /usr/local/bin/k3s-killall.sh ]]; then
+    sudo /usr/local/bin/k3s-killall.sh
+fi
+
+echo "Uninstalling k3s if present"
+if [[ -x /usr/local/bin/k3s-uninstall.sh ]]; then
+    sudo /usr/local/bin/k3s-uninstall.sh
+fi
+if [[ -x /usr/local/bin/k3s-agent-uninstall.sh ]]; then
+    sudo /usr/local/bin/k3s-agent-uninstall.sh
+fi
+
+sudo apt-get update
+sudo apt-get -y install jq unzip zip
+
+# Install go, task and kubectl WITHOUT snap: snapd mounts each snap via 
snapfuse
+# under WSL, which silently presents an empty mountpoint (meta/snap.yaml 
missing),
+# so `task`/`go`/`kubectl` fail. Direct binaries avoid the whole snap 
machinery.
+
+# Map dpkg arch (amd64/arm64) to the Go/k8s arch naming used by the download 
URLs.
+GOARCH="$(dpkg --print-architecture)"
+
+echo "Installing Go"
+GO_VERSION=1.26.4
+curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GOARCH}.tar.gz"; -o 
/tmp/go.tar.gz
+sudo rm -rf /usr/local/go
+sudo tar -C /usr/local -xzf /tmp/go.tar.gz
+rm -f /tmp/go.tar.gz
+# Make go available on PATH for this session and for future login shells.
+export PATH="/usr/local/go/bin:$PATH"
+echo 'export PATH=/usr/local/go/bin:$PATH' | sudo tee /etc/profile.d/go.sh 
>/dev/null
+
+echo "Installing Task"
+# Official installer drops the 'task' binary into the given -b directory.
+curl -fsSL https://taskfile.dev/install.sh | sudo sh -s -- -d -b /usr/local/bin
+
+echo "Installing kubectl"
+KUBECTL_VERSION="$(curl -fsSL https://dl.k8s.io/release/stable.txt)"
+curl -fsSL 
"https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${GOARCH}/kubectl"; -o 
/tmp/kubectl
+sudo install -m 0755 /tmp/kubectl /usr/local/bin/kubectl
+rm -f /tmp/kubectl
+
+export PATH="/usr/local/go/bin:/usr/local/bin:$PATH"
+
+echo "Building and testing"
+# cd into the source dir (where this script lives) so `task` finds the 
Taskfile,
+# regardless of the caller's working directory (e.g. a login shell resets it).
+cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+git config --global --add safe.directory "$PWD"
+git config --global --add safe.directory "$PWD/olaris-op"
+task build
+task test
diff --git a/build-and-test-windows.ps1 b/build-and-test-windows.ps1
new file mode 100755
index 0000000..04c273a
--- /dev/null
+++ b/build-and-test-windows.ps1
@@ -0,0 +1,136 @@
+#Requires -Version 5.1
+# Build-and-test driver for Windows via WSL.
+# - installs WSL if missing
+# - creates and starts an Ubuntu distribution
+# - initializes it non-interactively: removes k3s, creates a sudo user, sets 
it default
+# - Enter in the distro
+
+$ErrorActionPreference = "Stop"
+
+$Distro = "Ubuntu"
+$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
+
+# Default UNIX account created inside the distribution (override with env 
vars).
+$WslUser = if ($env:WSL_USER) { $env:WSL_USER } else { "ops" }
+$WslPassword = if ($env:WSL_PASSWORD) { $env:WSL_PASSWORD } else { "ops" }
+
+function Test-WslInstalled {
+    if (-not (Get-Command wsl.exe -ErrorAction SilentlyContinue)) {
+        return $false
+    }
+    # `wsl --status` returns a non-zero exit code when WSL is not usable.
+    wsl.exe --status *> $null
+    return ($LASTEXITCODE -eq 0)
+}
+
+Write-Host "Checking WSL is installed"
+if (-not (Test-WslInstalled)) {
+    Write-Host "WSL not found. Installing WSL with the $Distro distribution..."
+    wsl.exe --install -d $Distro
+    Write-Warning "WSL was just installed. A reboot is usually required to 
finish setup."
+    Write-Warning "Please reboot Windows and re-run this script."
+    exit 0
+}
+
+Write-Host "Removing any existing $Distro distribution for a clean build"
+$installed = (wsl.exe --list --quiet) -replace "`0", "" | ForEach-Object { 
$_.Trim() } | Where-Object { $_ }
+if ($installed -contains $Distro) {
+    Write-Host "Unregistering existing $Distro distribution..."
+    wsl.exe --unregister $Distro
+    if ($LASTEXITCODE -ne 0) {
+        Write-Error "Failed to unregister $Distro"
+        exit $LASTEXITCODE
+    }
+}
+
+Write-Host "Installing a fresh $Distro distribution"
+wsl.exe --install -d $Distro --no-launch
+if ($LASTEXITCODE -ne 0) {
+    Write-Error "Failed to install $Distro"
+    exit $LASTEXITCODE
+}
+
+Write-Host "Initializing $Distro as root (removing k3s, docker, creating user 
'$WslUser')"
+# On WSL there is no host user mapped in, so we create the build user 
ourselves.
+# We do it by running provisioning commands directly as root (wsl -u root), no
+# boot command. The script is idempotent: removes k3s, ensures docker, and
+# creates '$WslUser' with docker + passwordless sudo.
+$initScript = @"
+set -e
+
+# Remove k3s if it is installed inside the distribution.
+if [ -x /usr/local/bin/k3s-killall.sh ]; then /usr/local/bin/k3s-killall.sh; fi
+if [ -x /usr/local/bin/k3s-uninstall.sh ]; then 
/usr/local/bin/k3s-uninstall.sh; fi
+if [ -x /usr/local/bin/k3s-agent-uninstall.sh ]; then 
/usr/local/bin/k3s-agent-uninstall.sh; fi
+
+# Ensure docker is installed.
+command -v docker >/dev/null 2>&1 || curl -sL get.docker.com | sh
+
+# Create the build user if it does not already exist (idempotent).
+if ! id -u '$WslUser' >/dev/null 2>&1; then
+    useradd -m -s /bin/bash '$WslUser'
+    echo '${WslUser}:$WslPassword' | chpasswd
+fi
+
+# Add it to the docker + sudo groups and grant passwordless sudo.
+usermod -aG docker,sudo '$WslUser'
+echo '$WslUser ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/$WslUser
+chmod 440 /etc/sudoers.d/$WslUser
+
+# Make sure the docker daemon is running.
+service docker start >/dev/null 2>&1 || true
+
+# Mount Windows drives with 'metadata' so Unix permissions (including the
+# executable bit) are honored on /mnt/c. Without this, scripts on the mount
+# cannot be run directly (fork/exec fails with "no such file or directory").
+# Requires a `wsl --shutdown` to take effect (done below).
+mkdir -p /etc
+if [ ! -f /etc/wsl.conf ] || ! grep -q '^\[automount\]' /etc/wsl.conf; then
+    printf '[automount]\noptions = "metadata"\n' >> /etc/wsl.conf
+elif ! grep -q 'metadata' /etc/wsl.conf; then
+    sed -i '/^\[automount\]/a options = "metadata"' /etc/wsl.conf
+fi
+"@
+
+# Write the script to a BOM-less, LF-normalized temp file (PS 5.1 stdin pipes
+# prepend a BOM that bash chokes on), then run it as root inside the distro.
+$initFile = Join-Path ([System.IO.Path]::GetTempPath()) "wsl-init-$PID.sh"
+[System.IO.File]::WriteAllText($initFile, ($initScript -replace "`r`n", "`n"), 
(New-Object System.Text.UTF8Encoding($false)))
+try {
+    $wslInitPath = (wsl.exe -d $Distro wslpath -a ($initFile -replace '\\', 
'/')).Trim()
+    wsl.exe -d $Distro -u root -- bash "$wslInitPath"
+    if ($LASTEXITCODE -ne 0) {
+        Write-Error "Failed to initialize $Distro"
+        exit $LASTEXITCODE
+    }
+} finally {
+    Remove-Item -LiteralPath $initFile -ErrorAction SilentlyContinue
+}
+
+# Restart WSL so the /etc/wsl.conf 'metadata' automount option is applied.
+# Until the distro is remounted, /mnt/c ignores the executable bit and scripts
+# on it cannot be run directly.
+Write-Host "Restarting WSL to apply mount options"
+wsl.exe --shutdown
+
+Write-Host "Setting '$WslUser' as the default user for $Distro"
+# Use wsl.exe --manage: the per-distro launcher (e.g. Ubuntu.exe) is not 
always on
+# PATH and its name does not reliably match the distro name.
+wsl.exe --manage $Distro --set-default-user $WslUser
+if ($LASTEXITCODE -ne 0) {
+    Write-Error "Failed to set default user for $Distro"
+    exit $LASTEXITCODE
+}
+
+Write-Host "Running build-and-test-ubuntu.sh in $Distro as '$WslUser'"
+# Run the build/test script as ops from the source directory. ops was created
+# with the mount's owning uid/gid, so it can write the build output in place;
+# it has docker + passwordless sudo, so no newgrp/usermod is needed in-script.
+$wslScriptDir = (wsl.exe -d $Distro wslpath -a ($ScriptDir -replace '\\', 
'/')).Trim()
+wsl.exe -d $Distro --cd "$wslScriptDir" -u $WslUser -- bash -lc 
"./build-and-test-ubuntu.sh"
+if ($LASTEXITCODE -ne 0) {
+    Write-Error "build-and-test-ubuntu.sh failed with exit code $LASTEXITCODE"
+    exit $LASTEXITCODE
+}
+
+Write-Host "Done."
diff --git a/build-step.md b/build-step.md
new file mode 100644
index 0000000..cfd53aa
--- /dev/null
+++ b/build-step.md
@@ -0,0 +1,356 @@
+# Build Session Notes
+
+Date: 2026-06-27
+
+## Scope
+
+Work was done locally only. No git push and no Docker Hub push were performed.
+
+## Branches And Submodules
+
+- Root repository branch: `build`
+- `build` submodule branch: `build-local`
+- `build/openwhisk` submodule branch: `openwhisk-build-fixes`
+
+## OpenWhisk Source
+
+The nested `build/openwhisk` submodule was moved to the Nuvolaris commit:
+
+```text
+a456219d35bfabe4a3458fcce82cd71497a8524e
+```
+
+`build/.gitmodules` was updated to use:
+
+```text
+https://github.com/nuvolaris/openwhisk.git
+```
+
+## Build Devcontainer
+
+The correct build devcontainer is:
+
+```text
+build/.devcontainer/Dockerfile
+```
+
+The top-level `devcontainer` submodule was touched by mistake, then reverted. 
It is not part of the final build path.
+
+The build devcontainer was updated to be multi-arch and OpenWhisk-ready:
+
+- Java 11 via Temurin is the default `JAVA_HOME`
+- GraalVM Java 17 is still available for native-image
+- Docker CLI and buildx are installed
+- Docker repo setup uses the Ubuntu codename instead of a hardcoded `bionic`
+
+Verified inside the container:
+
+```text
+java 11.0.17
+javac 11.0.17
+native-image 17.0.9
+docker CLI available
+task available
+```
+
+## Gradle Fixes
+
+`task distdocker` initially failed with dependency resolution errors in the 
old OpenWhisk commit.
+
+Backported minimal Gradle fixes in `build/openwhisk`:
+
+- `build.gradle`: use `gradle.plugin.cz.alenkacz:gradle-scalafmt`
+- `settings.gradle`: `scalafmt` version `1.5.1`
+- `core/standalone/build.gradle`: `gradle-git-properties` version `2.4.2`
+
+These fixes are committed locally in:
+
+```text
+f2cba906 Fix OpenWhisk distDocker dependency resolution
+```
+
+## Java 17 Host Error
+
+Running OpenWhisk Gradle directly on the host failed with:
+
+```text
+Unsupported class file major version 61
+```
+
+Reason: host Java was 17, but this OpenWhisk/Gradle 6.9.1 build must run with 
Java 11.
+
+Fix: `build/Taskfile.yml` now wraps `distdocker` and `build-all` with `ops ide 
devcontainer`, so the host uses the same devcontainer path expected by OPS 
instead of a hand-written `docker run`.
+
+The wrapper also sets a temporary empty `DOCKER_CONFIG` inside the 
devcontainer.
+This avoids failures from a devcontainer-generated Docker credential helper, 
for
+example:
+
+```text
+error getting credentials - err: exit status 255
+```
+
+## Local Docker Build Tasks
+
+`build/Taskfile.yml` was changed so:
+
+- `task build` is the main local flow: build images, update OPS root, load 
kind, roll out controller
+- `task distdocker` runs through `ops ide devcontainer`
+- `task build-all` runs through `ops ide devcontainer`
+- `task build-all:local` checks that `openwhisk/common/scala` exists and 
prints a submodule init hint if it does not
+- `distdocker` no longer passes a Docker registry by default
+- `build-all` no longer uses `--push` for `ACT=build`
+- Push remains explicit via `buildx-and-push` / `ACT=buildx-push`
+
+Verified:
+
+```text
+cd /home/msciab/openserverless/build
+task build
+```
+
+This completed successfully locally through `ops ide devcontainer`. It built 
the
+OpenWhisk images, loaded controller/invoker/standalone into kind, and rolled 
out
+`controller-0`.
+
+Latest verified tag:
+
+```text
+2.0.0-incubating.2606291403
+```
+
+Latest verified pod image:
+
+```text
+controller-0 
registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2606291403
+```
+
+## OpenWhisk Directory
+
+`build/openwhisk` was converted from a nested Git submodule into a regular
+tracked directory inside the `build-local` branch.
+
+Reason: on a fresh server, `task build` failed when Docker tried to build:
+
+```text
+openwhisk/common/scala
+```
+
+The directory was missing because the nested OpenWhisk submodule had not been
+initialized. The `build-local` branch now vendors the OpenWhisk tree from 
commit
+`f2cba906`, including the local Gradle fixes, so a checkout of `build-local`
+contains `openwhisk/common/scala` directly.
+
+## Images Built Locally
+
+The OpenWhisk build produced these local Docker images:
+
+```text
+registry.hub.docker.com/apache/openserverless-wsk-scala:2.0.0-incubating.2506080813
+registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2506080813
+registry.hub.docker.com/apache/openserverless-wsk-invoker:2.0.0-incubating.2506080813
+registry.hub.docker.com/apache/openserverless-wsk-scheduler:2.0.0-incubating.2506080813
+registry.hub.docker.com/apache/openserverless-wsk-standalone:2.0.0-incubating.2506080813
+```
+
+Despite the `registry.hub.docker.com/apache` prefix, these were local tags 
only. They were not pushed.
+
+## OPS Root Image Override
+
+The installed OPS root was updated here:
+
+```text
+/home/msciab/.ops/0.1.0/olaris/opsroot.json
+```
+
+Changed keys:
+
+```json
+{
+  "standalone": 
"registry.hub.docker.com/apache/openserverless-wsk-standalone:2.0.0-incubating.2506080813",
+  "controller": 
"registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2506080813",
+  "invoker": 
"registry.hub.docker.com/apache/openserverless-wsk-invoker:2.0.0-incubating.2506080813"
+}
+```
+
+Important: in the current standalone OpenWhisk deployment path, OPS/operator 
uses `controller.image` for the controller pod. The `standalone` key is present 
in `opsroot.json`, but the observed `Whisk` resource uses 
`spec.controller.image`.
+
+## Kubeconfig Repair
+
+The host kubeconfig was stale:
+
+```text
+https://127.0.0.1:35889
+```
+
+The running kind control plane was exposed on:
+
+```text
+https://127.0.0.1:34101
+```
+
+Backed up kubeconfig:
+
+```text
+/home/msciab/.kube/config.bak.20260627085813
+```
+
+Updated context:
+
+```text
+kind-nuvolaris
+```
+
+Verified:
+
+```text
+kubectl cluster-info
+kubectl get nodes
+```
+
+## Loading Images Into Kind
+
+This is now automated by the build repository task:
+
+```bash
+cd /home/msciab/openserverless/build
+task build
+```
+
+That task runs:
+
+1. `task build-all`
+2. update of `/home/msciab/.ops/0.1.0/olaris/opsroot.json`
+3. import of local OpenWhisk images into the kind node
+4. rollout of the local OpenWhisk controller StatefulSet
+5. final status output
+
+The locally built images were not automatically present in the kind node.
+
+The underlying import command is:
+
+```bash
+for img in \
+  
registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2506080813
 \
+  
registry.hub.docker.com/apache/openserverless-wsk-invoker:2.0.0-incubating.2506080813
 \
+  
registry.hub.docker.com/apache/openserverless-wsk-standalone:2.0.0-incubating.2506080813
+do
+  docker save "$img" | docker exec -i nuvolaris-control-plane ctr 
--namespace=k8s.io images import -
+done
+```
+
+Verified in kind:
+
+```text
+registry.hub.docker.com/apache/openserverless-wsk-controller   
2.0.0-incubating.2506080813
+registry.hub.docker.com/apache/openserverless-wsk-invoker      
2.0.0-incubating.2506080813
+registry.hub.docker.com/apache/openserverless-wsk-standalone   
2.0.0-incubating.2506080813
+```
+
+## Current Pod Image
+
+The `Whisk` CR had the new image:
+
+```text
+spec.controller.image = 
registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2506080813
+```
+
+But the actual StatefulSet/pod initially still used:
+
+```text
+ghcr.io/nuvolaris/openwhisk-controller:0.3.0-morpheus.22122609
+```
+
+This is now automated by:
+
+```bash
+cd /home/msciab/openserverless/build
+task build
+```
+
+The underlying patch command is:
+
+```bash
+kubectl -n nuvolaris set image statefulset/controller \
+  
controller=registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2506080813
+```
+
+Rollout completed and `controller-0` now uses:
+
+```text
+registry.hub.docker.com/apache/openserverless-wsk-controller:2.0.0-incubating.2506080813
+```
+
+## Why `task build` / `task setup` Did Not Do This Automatically
+
+There are two separate build systems:
+
+1. Root `Taskfile.yml`
+   - Builds CLI, operator, runtimes, streamer, admin-api.
+   - Its `opsroot` task updates only:
+     - `operator`
+     - `streamer`
+     - `systemapi`
+   - It does not build or update OpenWhisk `controller` / `invoker` / 
`standalone`.
+   - It saves some images into `~/.ops/<os>-<arch>/images/kind`, but not the 
OpenWhisk images produced by `build/Taskfile.yml`.
+
+2. `build/Taskfile.yml`
+   - Builds OpenWhisk images:
+     - controller
+     - invoker
+     - scheduler
+     - standalone
+     - scala base
+   - Before this session, it did not update OPS `opsroot.json`.
+   - Before manual loading, it did not load these images into kind.
+
+Also, the operator/standalone image replacement appears to miss the new image 
when rendering the StatefulSet.
+
+Observed behavior:
+
+- The `Whisk` CR contains `spec.controller.image` with the new image.
+- The generated StatefulSet still had the old template image.
+
+Likely technical cause:
+
+- `olaris-op/nuvolaris/openwhisk_standalone.py` calls `kus.image(whisk_image, 
newTag=whisk_tag)`.
+- Kustomize image replacement matches the image name already present in the 
template.
+- The template contains `ghcr.io/nuvolaris/openwhisk-controller`.
+- The generated kustomization uses the new image as the match name, so it does 
not match the old template image.
+
+Proper code-level fix should replace the template image name with `newName`, 
for example:
+
+```text
+name: ghcr.io/nuvolaris/openwhisk-controller
+newName: registry.hub.docker.com/apache/openserverless-wsk-controller
+newTag: 2.0.0-incubating.2506080813
+```
+
+## Local Commits Created
+
+Root repo:
+
+```text
+bd8b2b4 Update build-all local workflow
+1796e13 Update build distdocker container wrapper
+35ae719 Update build distdocker local workflow
+d4d269d Update build submodule devcontainer toolchain
+d781ddb Update build submodule for Nuvolaris openwhisk source
+d758eab Point build submodule to local openwhisk update
+```
+
+Build submodule:
+
+```text
+3326ff6 Make build-all local and containerized
+f591434 Run distdocker through build container
+13ef155 Make distdocker local-only by default
+3492964 Make build devcontainer multi-arch OpenWhisk ready
+2c53f0f Use Nuvolaris openwhisk submodule source
+2fd1cf8 Point openwhisk to Nuvolaris action size change
+```
+
+OpenWhisk submodule:
+
+```text
+f2cba906 Fix OpenWhisk distDocker dependency resolution
+```
diff --git a/cli b/cli
index f991fd0..a601c07 160000
--- a/cli
+++ b/cli
@@ -1 +1 @@
-Subproject commit f991fd07e37768e750e2ce8f1971a0073e4ca848
+Subproject commit a601c075303135e65e7ee63e4ab1af2818be2364
diff --git a/devcontainer b/devcontainer
index e704655..f6538f1 160000
--- a/devcontainer
+++ b/devcontainer
@@ -1 +1 @@
-Subproject commit e7046558156861bd62540d88bdaca5aee34842f1
+Subproject commit f6538f12c16913a588ddbd51cb7c6b90e140e5c0
diff --git a/olaris b/olaris
index b5bf768..eb360c0 160000
--- a/olaris
+++ b/olaris
@@ -1 +1 @@
-Subproject commit b5bf7688ad76fa56394b70681d21681a7c93f26b
+Subproject commit eb360c093ec739edcca81cad10b72f4002cfd4e3
diff --git a/olaris-op b/olaris-op
index 84e48da..8e09c2f 160000
--- a/olaris-op
+++ b/olaris-op
@@ -1 +1 @@
-Subproject commit 84e48da96c5253120f19b5d03f7400fdbeca94bf
+Subproject commit 8e09c2f3a85921f1e3f616dbaed51a35336ad8b9
diff --git a/openserverless-cli.code-workspace 
b/openserverless-cli.code-workspace
deleted file mode 100644
index 34bbc8a..0000000
--- a/openserverless-cli.code-workspace
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "folders": [
-    {
-      "name": "cli",
-      "path": "cli"
-    },
-   { 
-      "name": "task",
-      "path": "task"
-    }
-  ],
-  "settings": {
-    "workbench.colorCustomizations": {
-      "activityBar.background": "#5b09e0",
-      "titleBar.activeBackground": "#5b09e0",
-      "titleBar.activeForeground": "#5b09e0",
-      "statusBar.background": "#5b09e0"
-    },
-    "go.goroot": 
"/nix/store/nnh57s7m672k6snkanhz1kb18skwjpbg-go-1.21.11/share/go"
-  }
-}
diff --git a/openserverless-operator.code-workspace 
b/openserverless-operator.code-workspace
deleted file mode 100644
index f802d83..0000000
--- a/openserverless-operator.code-workspace
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "folders": [
-            {
-                "name": "openserverless-operator",
-                "path": "operator"
-            }
-        ],
-    "settings": {
-            "workbench.colorCustomizations": {
-                    "activityBar.background": "#32cb0f",
-                    "titleBar.activeBackground": "#32cb0f",
-                    "titleBar.activeForeground": "#32cb0f",
-                    "statusBar.background": "#32cb0f"
-
-            }
-    }
-}
diff --git a/openserverless.code-workspace b/openserverless.code-workspace
deleted file mode 100644
index 852c8bb..0000000
--- a/openserverless.code-workspace
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "folders": [
-            {
-                "name": "operator",
-                "path": "operator"
-            },
-            {
-                "name": "site",
-                "path": "site"
-            },
-            { 
-                "name": "root",
-                "path": "."
-           }
-        ],
-    "settings": {
-            "workbench.colorCustomizations": {
-                    "activityBar.background": "#d2e313",
-                    "titleBar.activeBackground": "#d2e313",
-                    "titleBar.activeForeground": "#d2e313",
-                    "statusBar.background": "#d2e313"
-            }
-    }
-}
diff --git a/runtimes b/runtimes
index d1bc9ff..0300f37 160000
--- a/runtimes
+++ b/runtimes
@@ -1 +1 @@
-Subproject commit d1bc9ffee4634899241b60210c0323740deda066
+Subproject commit 0300f377f8ab3704462d9e3c63cef1892441417c
diff --git a/site b/site
deleted file mode 160000
index e45b68f..0000000
--- a/site
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit e45b68f3e8a36705d388ab5608d7cb256f55465c
diff --git a/streamer b/streamer
index 57dd328..99d4f0f 160000
--- a/streamer
+++ b/streamer
@@ -1 +1 @@
-Subproject commit 57dd32888ca610280dfaca1d47cca12a0526cc52
+Subproject commit 99d4f0f75936afda5404c593d91b6e1fa5dfda2e
diff --git a/testing b/testing
index 4784e06..bb6c50c 160000
--- a/testing
+++ b/testing
@@ -1 +1 @@
-Subproject commit 4784e064e0c0b171ceb93b9656d8d1c9f900346f
+Subproject commit bb6c50c892e37947fa801fdf68d2797bd50d8f57
diff --git a/vscode b/vscode
index 2d293c9..abcd703 160000
--- a/vscode
+++ b/vscode
@@ -1 +1 @@
-Subproject commit 2d293c9871a5b8ace39e6b42ab152675bb1967f9
+Subproject commit abcd703fb389c2df2171ce2d32da6068a914f415


Reply via email to