Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: "22"
node-version: "24"
cache: "pnpm"

- name: Install dependencies
Expand All @@ -65,7 +65,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: "22"
node-version: "24"
cache: "pnpm"

- name: Install dependencies
Expand All @@ -90,7 +90,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: "22"
node-version: "24"
cache: "pnpm"

- name: Install dependencies
Expand Down
13 changes: 8 additions & 5 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Resolve tool versions (bundled OpenCode and microsandbox for reproducibility)
- name: Set tool versions (pinned for reproducibility)
id: versions
run: |
UV_VERSION=$(git ls-remote --tags --sort=-v:refname https://github.com/astral-sh/uv.git 'refs/tags/[0-9]*' | head -1 | sed 's/.*refs\/tags\///')
OPENCODE_VERSION=1.18.16
MICROSANDBOX_VERSION=0.6.15
UV_VERSION=0.12.7
OPENCODE_VERSION=1.18.31
MICROSANDBOX_VERSION=0.7.2
PLAYWRIGHT_VERSION=1.63.0
echo "uv=${UV_VERSION}" >> $GITHUB_OUTPUT
echo "opencode=${OPENCODE_VERSION}" >> $GITHUB_OUTPUT
echo "microsandbox=${MICROSANDBOX_VERSION}" >> $GITHUB_OUTPUT
echo "Versions: uv=${UV_VERSION} (latest), opencode=${OPENCODE_VERSION} (bundled default), microsandbox=${MICROSANDBOX_VERSION} (pinned)"
echo "playwright=${PLAYWRIGHT_VERSION}" >> $GITHUB_OUTPUT
echo "Versions: uv=${UV_VERSION} (pinned), opencode=${OPENCODE_VERSION} (bundled default), microsandbox=${MICROSANDBOX_VERSION} (pinned), playwright=${PLAYWRIGHT_VERSION} (pinned)"

- name: Docker meta
id: meta
Expand Down Expand Up @@ -63,6 +65,7 @@ jobs:
UV_VERSION=${{ steps.versions.outputs.uv }}
OPENCODE_VERSION=${{ steps.versions.outputs.opencode }}
MICROSANDBOX_VERSION=${{ steps.versions.outputs.microsandbox }}
PLAYWRIGHT_VERSION=${{ steps.versions.outputs.playwright }}
cache-from: type=gha
cache-to: type=gha,mode=max
target: runner
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-ocm-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
node-version: '24'
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'

Expand Down
158 changes: 158 additions & 0 deletions .github/workflows/sandbox-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Sandbox Image

on:
workflow_dispatch:
inputs:
tag:
description: Extra tag to publish alongside the package version and commit sha
default: latest
required: false
pull_request:
paths:
- Dockerfile.sandbox
- scripts/sandbox-dockerd-start.sh
- .github/workflows/sandbox-image.yml

env:
IMAGE: docker.io/cstechdev/ocm-sandbox

permissions:
contents: read

jobs:
build:
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository
strategy:
fail-fast: true
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Platform slug
id: platform
run: echo "slug=${PLATFORM//\//-}" >> "$GITHUB_OUTPUT"
env:
PLATFORM: ${{ matrix.platform }}

- name: Login to Docker Hub
if: github.event_name == 'workflow_dispatch'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and verify native image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.sandbox
platforms: ${{ matrix.platform }}
outputs: ${{ github.event_name == 'workflow_dispatch' && format('type=image,name={0},push-by-digest=true,name-canonical=true,push=true', env.IMAGE) || 'type=cacheonly' }}
cache-from: type=gha,scope=sandbox-${{ steps.platform.outputs.slug }}
cache-to: type=gha,scope=sandbox-${{ steps.platform.outputs.slug }},mode=max

- name: Export digest
if: github.event_name == 'workflow_dispatch'
run: |
mkdir -p /tmp/digests
touch "/tmp/digests/${DIGEST#sha256:}"
env:
DIGEST: ${{ steps.build.outputs.digest }}

- name: Upload digest
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: digests-${{ steps.platform.outputs.slug }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
if: github.event_name == 'workflow_dispatch'
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Resolve tags
id: tags
run: |
version="$(jq -er .version package.json)"
tags="sha-${GITHUB_SHA::12} $version"
for tag in "$version" "$EXTRA_TAG"; do
if [ -n "$tag" ] && [[ ! "$tag" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$ ]]; then
printf 'Invalid image tag: %s\n' "$tag" >&2
exit 1
fi
done
if [ -n "$EXTRA_TAG" ]; then
tags="$tags $EXTRA_TAG"
fi
echo "tags=$tags" >> "$GITHUB_OUTPUT"
env:
EXTRA_TAG: ${{ inputs.tag }}

- name: Create manifest list and push
working-directory: /tmp/digests
run: |
read -ra tags <<< "$TAGS"
args=()
for tag in "${tags[@]}"; do
args+=(-t "$IMAGE:$tag")
done
digests=(*)
test "${#digests[@]}" -eq 2
for digest in "${digests[@]}"; do
[[ "$digest" =~ ^[a-f0-9]{64}$ ]]
args+=("$IMAGE@sha256:$digest")
done
docker buildx imagetools create "${args[@]}"
env:
TAGS: ${{ steps.tags.outputs.tags }}

- name: Report index digest
run: |
digest="$(docker buildx imagetools inspect "$IMAGE:sha-${GITHUB_SHA::12}" --format '{{json .Manifest.Digest}}' | tr -d '"')"
{
echo "## Sandbox image"
echo
echo "Tags: $TAGS"
echo
echo "Pin \`SANDBOX_IMAGE\` to:"
echo
echo '```'
echo "$IMAGE@$digest"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
echo "$IMAGE@$digest"
env:
TAGS: ${{ steps.tags.outputs.tags }}
21 changes: 15 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:24.13.0-trixie AS base
FROM node:24.21.0-trixie AS base

RUN apt-get update && apt-get install -y \
git \
Expand Down Expand Up @@ -26,7 +26,7 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | d
&& apt-get update && apt-get install -y gh \
&& rm -rf /var/lib/apt/lists/*

RUN corepack enable && corepack prepare pnpm@latest --activate
RUN corepack enable && corepack prepare pnpm@10.28.1 --activate

RUN curl -fsSL https://bun.sh/install | bash && \
mv /root/.bun /opt/bun && \
Expand Down Expand Up @@ -58,18 +58,23 @@ RUN pnpm --filter frontend build

FROM base AS runner

ARG UV_VERSION=latest
ARG OPENCODE_VERSION=1.18.16
ARG MICROSANDBOX_VERSION=0.6.15
# uv 0.12.8 and later segfault under qemu-user x86_64 emulation, which is how
# an arm64 host builds the amd64 platform; 0.12.7 is the newest verified-good
# release, so re-verify a bump there before moving it.
ARG UV_VERSION=0.12.7
ARG OPENCODE_VERSION=1.18.31
ARG MICROSANDBOX_VERSION=0.7.2
ARG PLAYWRIGHT_VERSION=1.63.0
# Bump TOOLS_CACHEBUST (e.g. via --build-arg) to force a fresh uv/opencode
# install without invalidating the rest of the build cache.
ARG TOOLS_CACHEBUST=0

RUN echo "Installing uv=${UV_VERSION} opencode=${OPENCODE_VERSION} (cachebust=${TOOLS_CACHEBUST})" && \
curl -LsSf https://astral.sh/uv/install.sh | UV_NO_MODIFY_PATH=1 sh && \
curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | UV_NO_MODIFY_PATH=1 sh && \
mv /root/.local/bin/uv /usr/local/bin/uv && \
mv /root/.local/bin/uvx /usr/local/bin/uvx && \
chmod +x /usr/local/bin/uv /usr/local/bin/uvx && \
test "$(uv --version | cut -d' ' -f2)" = "${UV_VERSION}" && \
echo "Downloading opencode ${OPENCODE_VERSION}..." && \
OC_ARCH=$(uname -m) && \
if [ "$OC_ARCH" = "aarch64" ]; then OC_ARCH="arm64"; fi && \
Expand Down Expand Up @@ -116,6 +121,10 @@ RUN echo "Installing microsandbox=${MICROSANDBOX_VERSION} (cachebust=${TOOLS_CAC
chmod -R a+rX /opt/microsandbox && \
msb --version

RUN echo "Installing Chromium runtime libraries for playwright=${PLAYWRIGHT_VERSION} (cachebust=${TOOLS_CACHEBUST})" && \
npx --yes "playwright@${PLAYWRIGHT_VERSION}" install-deps chromium && \
rm -rf /var/lib/apt/lists/* /root/.npm

ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=5003
Expand Down
Loading
Loading